閱讀目錄html
1 namespace AutofacDemo 2 { 3 class Program 4 { 5 //用於存儲容器的屬性 6 private static IContainer Container { get; set; } 7 static void Main(string[] args) 8 { 9 //獲取容器 10 var builder = new ContainerBuilder(); 11 //註冊組件(類),並公開服務(接口) 12 builder.RegisterType<ConsoleOutput>().As<IOutput>(); 13 builder.RegisterType<TodayWriter>().As<IDateWriter>(); 14 //存儲容器 15 Container = builder.Build(); 16 17 WriteDate();//輸出當前的日期 18 } 19 public static void WriteDate() 20 { 21 using (var scope=Container.BeginLifetimeScope()) 22 { 23 //解析組件(功能相似於new一個IDateWriter的實現類) 24 var writer = scope.Resolve<IDateWriter>(); 25 writer.WriteDate(); 26 } 27 } 28 } 29 //輸出功能接口 30 public interface IOutput 31 { 32 void Write(string content); 33 } 34 //控制檯輸出類 35 public class ConsoleOutput : IOutput 36 { 37 public void Write(string content) 38 { 39 Console.WriteLine(content); 40 } 41 } 42 //輸出日期的接口 43 public interface IDateWriter 44 { 45 void WriteDate(); 46 } 47 48 //輸出今天日期的類 49 public class TodayWriter : IDateWriter 50 { 51 private IOutput _output;//輸出日期的類依賴IOutput 52 public TodayWriter(IOutput output) 53 { 54 this._output = output; 55 } 56 public void WriteDate() 57 { 58 this._output.Write(DateTime.Today.ToShortDateString()); 59 } 60 } 61 }
應用程序執行過程:函數
「WriteDate」方法向Autofac詢問IDateWriter。ui
Autofac看到IDateWriter映射到TodayWriter,因此開始建立一個TodayWriter。this
Autofac認爲TodayWriter在其構造函數中須要一個IOutput。spa
Autofac看到IOutput映射到ConsoleOutput,因此建立一個新的ConsoleOutput實例。.net
Autofac使用新的ConsoleOutput實例來完成TodayWriter的構建。code
Autofac將「WriteDate」的徹底構建的TodayWriter返回給消費者。htm
以後,若是您但願應用程序編寫不一樣的日期,則能夠實現不一樣的IDateWriter,而後在應用程序啓動時更改註冊。你沒必要改變任何其餘類。 這樣就實現了反轉控制!對象
使用Autofac 註冊組件的任務是:經過建立一個ContainerBuilder而且告知builder 哪些組件公開哪些服務。blog
1 // 建立組件/服務註冊的容器 2 var builder = new ContainerBuilder(); 3 5 ////----------------------1、反射組件----------------//// 6 // 反射組件方法1---經過類型註冊 7 builder.RegisterType<ConsoleOutput>().As<IOutput>(); 8 // 反射組件方法2---經過構造函數註冊 9 builder.RegisterType<TodayWriter>() 10 .UsingConstructor(typeof(IOutput)).As<IDateWriter>(); 11 12 13 14 ////--------------------2、實例組件----------------------//// 15 // 註冊建立的對象實例,把該實例做爲一個服務 16 var output = new ConsoleOutput(); 17 builder.RegisterInstance(output).As<IOutput>(); 18 //不影響系統中原有的單例 19 builder.RegisterInstance(MySingleton.GetInstance()).ExternallyOwned(); 20 21 22 23 ////------------------3、Lambda表達式組件---------------//// 24 //參數c是組件上下文(一個IComponentContext對象) ,此處該組件被建立。您可使用它來解析來自於容器的其餘組件,從而幫助你建立組件。 25 26 builder.Register(c => new TodayWriter(c.Resolve<IOutput>())).As<IDateWriter>(); 27 28 //分離組件建立最大的好處就是具體類型能夠變化 29 //一個組件分離的Demo:註冊一個信用卡組件 30 builder.Register<CreditCard>( 31 (c, p) => 32 { 33 var accountId = p.Named<string>("accountId"); 34 if (accountId.StartsWith("9")) 35 { 36 return new GoldCard(accountId); 37 } 38 else 39 { 40 return new StandardCard(accountId); 41 } 42 }); 43 //根據參數不一樣獲取不一樣種類的信用卡類實例 44 var card = container.Resolve<CreditCard>(new NamedParameter("accountId", "12345")); 45 46 47 ////-------------------------4、泛型註冊------------------//// 48 //泛型註冊,能夠經過容器返回List<T> 如:List<string>,List<int>等等 49 builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope(); 50 using (IContainer container = builder.Build()) 51 { 52 IList<string> ListString = container.Resolve<IList<string>>(); 53 } 54 55 56 ////-----------------------5、服務與組件-------------------//// 57 builder.RegisterType<ConsoleLogger>();//默認把註冊類型做爲公開服務 58 builder.RegisterType<ConsoleLogger>().As<ILogger>().As<IMyLogger>();//能夠公開任意多個服務,可是默認的註冊類型會被覆蓋 59 builder.RegisterType<ConsoleLogger>().AsSelf().As<ILogger>();//加上AsSelf()默認的註冊類型不會被覆蓋 60 //當公開的服務重名時,服務使用的默認組件是後註冊的那個 61 builder.Register<ConsoleLogger>().As<ILogger>(); 62 builder.Register<FileLogger>().As<ILogger>();//默認使用後註冊的FileLogger 63 //阻止該默認行爲,使用builder.Register<FileLogger>().As<ILogger>().PreserveExistingDefaults(),這樣不會覆蓋之前註冊的組件 64 65 66 ////-----------6、條件註冊(IfNotRegistered,OnlyIf)-------//// 67 //HandlerC不會被註冊 68 builder.RegisterType<HandlerA>() 69 .AsSelf() 70 .As<IHandler>() 71 .IfNotRegistered(typeof(HandlerB)); 72 builder.RegisterType<HandlerB>() 73 .AsSelf() 74 .As<IHandler>(); 75 builder.RegisterType<HandlerC>() 76 .AsSelf() 77 .As<IHandler>() 78 .IfNotRegistered(typeof(HandlerB)); 79 80 //只有IService和HandlerB都註冊時,纔會去註冊Manager 81 builder.RegisterType<Manager>() 82 .As<IManager>() 83 .OnlyIf(reg => 84 reg.IsRegistered(new TypedService(typeof(IService))) && 85 reg.IsRegistered(new TypedService(typeof(HandlerB)))); 86 87 88 // 編譯容器完成註冊且準備對象解析 89 Container = builder.Build(); 90 91 // 如今你可使用 Autofac 解析服務. 例如,這行將執行註冊的lambda表達式對於 IConfigReader 服務. 92 using (var scope = Container.BeginLifetimeScope()) 93 { 94 var writer = Container.Resolve<IOutput>(); 95 var dataWriter = Container.Resolve<IDateWriter>(); 96 writer.Write("111");//輸出111 97 dataWriter.WriteDate();//輸出當前日期 98 Console.ReadKey(); 99 }
Autofac支持的參數類型有三種:
NamedParameter - 經過名稱匹配目標參數
TypedParameter - 經過類型匹配目標參數(須要精確匹配類型)
ResolvedParameter - 靈活的參數匹配
例子:一個讀取配置文件的類,構造器須要傳入參數:節點名稱
1 public class ConfigReader : IConfigReader 2 { 3 public ConfigReader(string configSectionName) 4 { 5 // 存儲配置的節點名稱 6 } 7 8 // ...讀取基於節點名稱的配置 9 }
Parameters with Reflection Components----註冊時傳入
1 // 使用一個命名參數: 2 builder.RegisterType<ConfigReader>() 3 .As<IConfigReader>() 4 .WithParameter("configSectionName", "mySectionName"); 5 6 // 使用一個類型參數: 7 builder.RegisterType<ConfigReader>() 8 .As<IConfigReader>() 9 .WithParameter(new TypedParameter(typeof(string), "mySectionName")); 10 11 // 使用一個解析參數: 12 builder.RegisterType<ConfigReader>() 13 .As<IConfigReader>() 14 .WithParameter( 15 new ResolvedParameter( 16 (pi, ctx) => pi.ParameterType == typeof(string) && pi.Name == "configSectionName", 17 (pi, ctx) => "mySectionName"));
Parameters with Lambda Expression Components----解析時傳入
在組件註冊表達式中,你能夠經過改變委託簽名使用傳入參數進行註冊,代替僅僅接收一個IComponentContext參數,一個IComponentContext 和 IEnumerable<Parameter>參數:
1 builder.Register((c, p) => 2 new ConfigReader(p.Named<string>("configSectionName"))) 3 .As<IConfigReader>();
當你解析參數時,你的lambda將使用這些參數來傳入值:
var reader = scope.Resolve<IConfigReader>(new NamedParameter("configSectionName", "mySectionName"));
參考文章:
一、https://blog.csdn.net/chiyueqi/article/details/52446569
二、http://www.yuanjiaocheng.net/Autofac/register-parameters.html