您好,登錄后才能下訂單哦!
這篇文章主要介紹“asp.net core中的IOC是什么”,在日常操作中,相信很多人在asp.net core中的IOC是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”asp.net core中的IOC是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
先來給大家解釋幾個概念,IOC全稱Inversion of Control,翻譯過來就是控制反轉,是面向對象編程的一種設計原則,用來降低代碼之間的耦合度。所謂的控制反轉簡單來講就是將類中屬性或者其他參數的初始化交給其他方處理,而不是直接使用構造函數。
public class Demo1
{
}
public class Demo2
{
public Demo1 demo;
}
對于以上簡單示例代碼中,在Demo2類中持有了一個Demo1的實例。如果按照之前的情況來講,我們會通過以下方法為demo賦值:
// 方法一
public Demo1 demo = new Demo1();
// 方法二
public Demo2()
{
demo = new Demo1();
}
這時候,如果Demo1變成下面的樣子:
public class Demo1
{
public Demo1(Demo3 demo3)
{
// 隱藏
}
}
public class Demo3
{
}
那么,如果Demo2 沒有持有一個Demo3的實例對象,這時候創建Demo1的時候就需要額外構造一個Demo3。如果Demo3需要持有另外一個類的對象,那么Demo2中就需要多創建一個對象。最后就會發現這樣就陷入了一個構造“地獄”(我發明的詞,指這種為了一個對象卻得構造一大堆其他類型的對象)。
實際上,對于Demo2并不關心Demo1的實例對象是如何獲取的,甚至都不關心它是不是Demo1的子類或者接口實現類。我在示例中使用了類,但這里可以同步替換成Interface,替換之后,Demo2在調用Demo1的時候,還需要知道Demo1有實現類,以及實現類的信息。
為了解決這個問題,一些高明的程序員們提出了將對象的創建這一過程交給第三方去操作,而不是調用類來創建。于是乎,上述代碼就變成了:
public class Demo2
{
public Demo1 Demo {get;set;}
public Demo2(Demo1 demo)
{
Demo = demo;
}
}
似乎并沒有什么變化?對于Demo2來說,Demo2從此不再負責Demo1的創建,這個步驟交由Demo2的調用方去創建,Demo2從此從負責維護Demo1這個對象的大麻煩中解脫了。
但實際上構造地獄的問題還是沒有解決,只不過是通過IOC的設計將這一步后移了。這時候,那些大神們想了想,不如開發一個框架這些實體對象吧。所以就出現了很多IOC框架:AutoFac、Sping.net、Unity等。
說到IOC就不得不提一下DI(Dependency Injection)依賴注入。所謂的依賴注入就是屬性對應實例通過構造函數或者使用屬性由第三方進行賦值。也就是最后Demo2的示例代碼中的寫法。
早期IOC和DI是指一種技術,后來開始確定這是不同的描述。IOC描述的是一種設計模式,而DI是一種行為。
在之前的ASP.NET 框架中,微軟并沒有提供默認的IOC支持。在最新的asp.net core中微軟提供了一套IOC支持,該支持在命名空間:
Microsoft.Extensions.DependencyInjection
里,在代碼中引用即可。
主要通過以下幾組方法實現:
public static IServiceCollection AddScoped<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddSingleton<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddTransient<TService>(this IServiceCollection services) where TService : class;
這里只列出了這三組方法的一種重載版本。
這三組方法分別代表三種生命周期:
AddScored 表示對象的生命周期為整個Request請求
AddTransient 表示每次從服務容器進行請求時創建的,適合輕量級、 無狀態的服務
AddSingleton 表示該對象在第一次從服務容器請求后獲取,之后就不會再次初始化了
這里每組方法只介紹了一個版本,但實際上每個方法都有以下幾個版本:
public static IServiceCollection AddXXX<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Type implementationType);
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory);
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType);
public static IServiceCollection AddXXX<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class;
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
where TService : class
where TImplementation : class, TService;
其中:implementationFactory 表示通過一個Provider實現TService/TImplementation 的工廠方法。當方法指定了泛型的時候,會自動依據泛型參數獲取要注入的類型信息,如果沒有使用泛型則必須手動傳入參數類型。
asp.net core如果使用依賴注入的話,需要在Startup方法中設置,具體內容可以參照以下:
public void ConfigureServices(IServiceCollection services)
{
//省略其他代碼
services.AddScoped<ISysUserAuthRepository,SysUserAuthRepository>();
}
asp.net core 為DbContext提供了不同的IOC支持,AddDbContext:
public static IServiceCollection AddDbContext<TContext>(
this IServiceCollection serviceCollection,
Action<DbContextOptionsBuilder> optionsAction = null,
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
where TContext : DbContext;
使用方法如下:
services.AddDbContext<DefaultContext>();
理論上,asp.net core的IOC已經足夠好了,但是依舊原諒我的貪婪。如果有二三百個業務類需要我來設置的話,我寧愿不使用IOC。因為那配置起來就是一場極其痛苦的過程。不過,可喜可賀的是AutoFac可以讓我免受這部分的困擾。
這里簡單介紹一下如何使用AutoFac作為IOC管理:
cd Web # 切換目錄到Web項目
dotnet package add Autofac.Extensions.DependencyInjection # 添加 AutoFac的引用
因為asp.net core 版本3更改了一些邏輯,AutoFac的引用方式發生了改變,現在不介紹之前版本的內容,以3為主。使用AutoFac需要先在 Program類里設置以下代碼:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) // 添加這行代碼
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
在Program類里啟用AutoFac的一個Service提供工廠類。然后在Startup類里添加如下方法:
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<DefaultContext>().As<DbContext>()
.WithParameter("connectStr","Data Source=./demo.db")
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(Assembly.Load("Web"))
.Where(t => t.BaseType.FullName.Contains("Filter"))
.AsSelf();
builder.RegisterAssemblyTypes(Assembly.Load("Domain"),
Assembly.Load("Domain.Implements"), Assembly.Load("Service"), Assembly.Load("Service.Implements"))
.AsSelf()
.AsImplementedInterfaces()
.InstancePerLifetimeScope()
.PropertiesAutowired();
}
修改:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
options.Filters.Add<UnitOfWorkFilterAttribute>();
}).AddControllersAsServices();// 這行新增
// 省略其他
}
到此,關于“asp.net core中的IOC是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。