日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

依赖注入之Autofac使用总结

發布時間:2025/5/22 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 依赖注入之Autofac使用总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

依賴倒置?控制反轉(IOC)? 依賴注入(DI)?

你是否還在被這些名詞所困擾,是否看了大量理論文章后還是一知半解了?

今天我想結合實際項目,和正在迷惑中的新手朋友一起來學習和總結依賴注入Autofac的使用和理解。

依賴注入粗暴理解

依賴:?

public class A {public A(B b){// do something } }

這樣的代碼,估計沒有程序猿不曾使用。

A類實例化的時候需要一個B的對象作為構造函數的參數,那么A就依賴B,這就叫依賴。

當然,不用構造函數的方式,在A類內部去new一個B,其實也是一樣存在A依賴B。

注入:

看到“注入”一詞,第一想到的是不是注射器?哈哈,還生活在童年陰影中。 結合一下“打針”這個場景來簡單理解下依賴注入。
醫生使用注射器(Autofac),將藥物(依賴=類對象),注入到血管(其他類中)。

Autofac的基本使用

搭建項目

創建一個MVC項目,通過Nuget直接添加Autofac。

?注入類本身.AsSelf()

public class TestController : Controller{private readonly InjectionTestService _testService;public TestController(InjectionTestService testService){_testService = testService;}public ActionResult Index(){ViewBag.TestValue = _testService.Test();return View();}} public class InjectionTestService : IService{public string Test(){return "Success";}}

在Global.asax中加入依賴注入的注冊代碼

// 創建一個容器var builder = new ContainerBuilder();// 注冊所有的Controller builder.RegisterControllers(Assembly.GetExecutingAssembly());// RegisterType方式:builder.RegisterType<InjectionTestService>().AsSelf().InstancePerDependency();// Register方式:builder.Register(c => new InjectionTestService()).AsSelf().InstancePerDependency();// 自動注入的方式,不需要知道具體類的名稱/* BuildManager.GetReferencedAssemblies()* 程序集的集合,包含 Web.config 文件的 assemblies 元素中指定的程序集、* 從 App_Code 目錄中的自定義代碼生成的程序集以及其他頂級文件夾中的程序集。*/// 獲取包含繼承了IService接口類的程序集var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly =>assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) !=null);// RegisterAssemblyTypes 注冊程序集var enumerable = assemblies as Assembly[] ?? assemblies.ToArray();if (enumerable.Any()){builder.RegisterAssemblyTypes(enumerable).Where(type => type.GetInterfaces().Contains(typeof(IService))).AsSelf().InstancePerDependency();}// 把容器裝入到微軟默認的依賴注入容器中var container = builder.Build();DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

為接口注入具體類.AsImplementedInterfaces()

public class TestController : Controller{private readonly IService _testService;public TestController(IService testService){_testService = testService;}public ActionResult Index(){ViewBag.TestValue = _testService.Test();return View();}} // Register 方式指定具體類builder.Register(c => new InjectionTestService()).As<IService>().InstancePerDependency();// RegisterType 方式指定具體類builder.RegisterType<InjectionTestService>().As<IService>().InstancePerDependency();// 自動注冊的方式// 獲取包含繼承了IService接口類的程序集var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly =>assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) !=null);// RegisterAssemblyTypes 注冊程序集var enumerable = assemblies as Assembly[] ?? assemblies.ToArray();if (enumerable.Any()){builder.RegisterAssemblyTypes(enumerable).Where(type => type.GetInterfaces().Contains(typeof(IService))).AsImplementedInterfaces().InstancePerDependency();}

?利用Named自動注入依賴類

需求場景說明:

有A、B、C三個短信平臺提供發送短信業務;

分別有三個短信平臺的實現類,AMessage,BMessage,CMessage;

客戶端在不同時段選取不同平臺發送短信。

常規簡單處理方式

新建三個服務類,AMsgService,BMsgService,CMsgService。
在客戶端通過 if else 的方式判斷要選用哪個短信平臺,然后new服務類對象,再調用Send方法發送短信。

缺點

如果有新的短信平臺D加入的話,必須新建一個DSendMsgService,然后修改客戶端if else 代碼。

改造

抽象一個短信平臺的接口 public interface IMessage{decimal QueryBalance();bool Send(string msg);int TotalSend(DateTime? startDate, DateTime? endDate);}

?具體實現類

[MessagePlatform(Enums.MPlatform.A平臺)]public class ASendMessageService : IMessage{public decimal QueryBalance(){return 0;}public bool Send(string msg){return true;}public int TotalSend(DateTime? startDate, DateTime? endDate){return 100;}}

類有一個自定義屬性標簽MessagePlatform,這個是干嘛了? 是為了給這個類做一個標記,結合Named使用,實現自動注入。

public class TestController : Controller{private Func<int, IMessage> _factory;public TestController(Func<int, IMessage> factory){_factory = factory;}public ActionResult Index(){var retult = _factory((int)Enums.MPlatform.A平臺).Send("去你的吧");return View(retult);}}

構造函數參數居然是一個func的委托?

這個factory傳入參數是一個int(定義好的短信平臺枚舉值),就可以拿到這個短信平臺具體的實現類?

沒錯,autofac就是這么任性。

builder.RegisterType<ASendMessageService>().Named<IMessage>((// 獲取類自定義屬性typeof(ASendMessageService).GetCustomAttributes(typeof(MessagePlatformAttribute), false).FirstOrDefault()as MessagePlatformAttribute).platform.ToString()).InstancePerRequest();builder.Register<Func<int, IMessage>>(c =>{var ic = c.Resolve<IComponentContext>();return name => ic.ResolveNamed<IMessage>(name.ToString());});

疑問:

上面只是給?ASendMessageService類實現了自動注入,那么BSendMessageService,CSendMessageService怎么辦了,不可能都去復制一段注入的配置代碼吧?

typeof(IMessage).Assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IMessage))).ForEach(type =>{// 注冊type});

如果你有些實現類不在IMessge這個程序集下,那就不能這么寫了,要結合具體項目情況來調整代碼。

總結

1.依賴注入的目的是為了解耦。

2.不依賴于具體類,而依賴抽象類或者接口,這叫依賴倒置。

3.控制反轉即IoC (Inversion of Control),它把傳統上由程序代碼直接操控的對象的調用權交給容器,通過容器來實現對象組件的裝配和管理。所謂的“控制反轉”概念就是對組件對象控制權的轉移,從程序代碼本身轉移到了外部容器。

4. 微軟的DependencyResolver如何創建controller 【后續學習】

Autofac創建類的生命周期

1、InstancePerDependency

對每一個依賴或每一次調用創建一個新的唯一的實例。這也是默認的創建實例的方式。

官方文檔解釋:Configure the component so that every dependent component or call to Resolve() gets a new, unique instance (default.)?

2、InstancePerLifetimeScope

在一個生命周期域中,每一個依賴或調用創建一個單一的共享的實例,且每一個不同的生命周期域,實例是唯一的,不共享的。

官方文檔解釋:Configure the component so that every dependent component or call to Resolve() within a single ILifetimeScope gets the same, shared instance. Dependent components in different lifetime scopes will get different instances.?

3、InstancePerMatchingLifetimeScope

在一個做標識的生命周期域中,每一個依賴或調用創建一個單一的共享的實例。打了標識了的生命周期域中的子標識域中可以共享父級域中的實例。若在整個繼承層次中沒有找到打標識的生命周期域,則會拋出異常:DependencyResolutionException。

官方文檔解釋:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope tagged with any of the provided tags value gets the same, shared instance. Dependent components in lifetime scopes that are children of the tagged scope will share the parent's instance. If no appropriately tagged scope can be found in the hierarchy an?DependencyResolutionException?is thrown.?

4、InstancePerOwned

在一個生命周期域中所擁有的實例創建的生命周期中,每一個依賴組件或調用Resolve()方法創建一個單一的共享的實例,并且子生命周期域共享父生命周期域中的實例。若在繼承層級中沒有發現合適的擁有子實例的生命周期域,則拋出異常:DependencyResolutionException。

官方文檔解釋:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope created by an owned instance gets the same, shared instance. Dependent components in lifetime scopes that are children of the owned instance scope will share the parent's instance. If no appropriate owned instance scope can be found in the hierarchy an?DependencyResolutionException?is thrown.?

5、SingleInstance

每一次依賴組件或調用Resolve()方法都會得到一個相同的共享的實例。其實就是單例模式。

官方文檔解釋:Configure the component so that every dependent component or call to Resolve() gets the same, shared instance.?

6、InstancePerHttpRequest? (新版autofac建議使用InstancePerRequest)

在一次Http請求上下文中,共享一個組件實例。僅適用于asp.net mvc開發。 官方文檔解釋:Share one instance of the component within the context of a single HTTP request.

?

?參考文檔:
https://stackoverflow.com/questions/2888621/autofacs-funct-to-resolve-named-service http://blog.csdn.net/dhx20022889/article/details/9061483


本文博客園地址:http://www.cnblogs.com/struggle999/p/6986903.html?
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!歡迎各位轉載,但是未經作者本人同意,轉載文章之后必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。

轉載于:https://www.cnblogs.com/struggle999/p/6986903.html

總結

以上是生活随笔為你收集整理的依赖注入之Autofac使用总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。