1. 程式人生 > >.Net Core中IOC容器的使用

.Net Core中IOC容器的使用

打程式碼之前先說一下幾個概念,那就是什麼是IOC、DI、DIP

雖然網上講這些的已經有很多了,我這裡還是要再贅述一下

IOC容器就是一個工廠,負責建立物件的
IOC控制反轉:只是把上端對下端的依賴,換成第三方容器決定
DI依賴注入:就是在構造某個物件時,能將物件依賴的東西自動的初始化進去
正是因為要實現IOC,所以才誕生了DI的技術手段
DIP就是上層模組不應該依賴底層模組,它們都應該依賴於抽象,具體點是Service不應該依賴於Repository,而應該依賴於IRepository

.Net Core中自帶了輕量級的IOC的容器

依次是Transient、Scoped、Singleton

services.AddTransient<>():服務在每次請求時被建立,適合無狀態的服務

services.AddScoped<>():服務每個請求只建立一次

services.Singleton<>():單例,只建立一次,第一次被請求的時候被建立

code部分:

定義一個介面ICacheContext和一個實現類CacheContext

 

 假如我們現在想要使用CacheContext類中的方法,按照我們以前的思路肯定是:

//例項化
CacheContext context=new CacheContext();
//呼叫方法
context.method();

這就產生了依賴!我們要依賴於抽象不能依賴於具體實現細節,這樣做:

//例項化
ICacheContext context=new CacheContext();
//呼叫方法
context.method();

接下來用IOC容器實現,將物件交給IOC容器託管。

這樣之後可以使用建構函式、屬性、方法進行注入

這裡使用建構函式注入,如下:

 

 接下來使用第三方IOC容器:Autofac

導包:Autofac與Autofac.Extensions.DependencyInjection

在Program中,加入如下程式碼:

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())//配置UseServiceProviderFactory
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

在Startup中加入一個方法:

 public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterType<CacheContext>().As<ICacheContext>();
        }

還是一樣在Controller中使用建構函式注入,和上面一樣

但是在真實的專案開發中不可能一個個的寫

我們可以通過反射載入程式集的強名稱,但是api層必須要對其引用

例如我這裡api層引用了Icewo.BaseManage.MSSQLDB層

 在ConfigureContainer方法中新增如下程式碼

 var assemblysServicesNoInterfaces = Assembly.Load("Icewo.BaseManage.MSSQLDB");
 builder.RegisterAssemblyTypes(assemblysServicesNoInterfaces);
Icewo.BaseManage.MSSQLDB層是沒有實現層的,也就是說他沒有介面層
如果是有介面層的話,方法又不一樣了
例如我這裡有Business層和IBusiness層,如果api層直接對Business層進行引用,這就造成程式高度耦合。所以api層只引用IBusiness層=》DIP(依賴倒置)

 在ConfigureContainer中新增如下方法:

注意:你要拷貝Business.dll到api層的bin目錄下或者改一下輸出路徑,不然啟動的時候會報錯。

 var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
 var businessDllFile = Path.Combine(basePath, "Icewo.BaseManage.Business.dll");
 var assemblysBusiness = Assembly.LoadFrom(businessDllFile);
 builder.RegisterAssemblyTypes(assemblysBusiness)
 .AsImplementedInterfaces()
 .InstancePerDependency();

還是一樣在Controllers中以建構函式注入的方式進行呼叫

水平有限,但是希望能幫到大家。

END