1. 程式人生 > >IoC之AutoFac(二)——解析服務

IoC之AutoFac(二)——解析服務

動態 static 運行時 log gis 3.3 http 當前 可能

1、Resolve方法

在您的組件註冊了適當的服務後,您可以從內置的容器和子生命周期範圍中解析服務。 您可以使用Resolve()方法,還是使用上篇的例子:

 1     private static IContainer Container { get; set; }
 2         static void Main(string[] args)
 3         {
 4             var builder = new ContainerBuilder();
 5             //註冊服務
 6             builder.RegisterType<ConsoleOutput>().As<IOutput>();
7 Container = builder.Build(); 8 //解析服務 9 using (var scope=Container.BeginLifetimeScope()) 10 { 11 var output= scope.Resolve<IOutput>(); 12 output.Write("outputsomething"); 13 Console.ReadKey(); 14 }
15 }

  解析服務時,Autofac將自動鏈接服務的整個依賴關系層次,並解析完全構建服務所需的任何依賴關系。 如果您的循環依賴關系被錯誤地處理,或者缺少必需的依賴關系,那麽您將得到一個DependencyResolutionException。

2、TryResolve和ResolveOptional方法

如果您有可能註冊或可能不被註冊的服務,您可以使用ResolveOptional()或TryResolve()來嘗試對服務進行有條件解決:

 1                 //解析服務
 2                 using (var scope = Container.BeginLifetimeScope())
3 { 4 //1.ResolveOptional:IOutput註冊的話解析,未被註冊返回null 5 var service = scope.ResolveOptional<IOutput>(); 6 7 //2.TryResolve:IOutput註冊的話解析獲取一個類型實例,未註冊返回null 8 IOutput output = null; 9 //如果有IOutPut服務,執行輸出 10 if (scope.TryResolve<IOutput>(out output)) 11 { 12 output.Write("outputsomething"); 13 } 14 Console.ReadKey(); 15 }

3、解析服務時傳參

  解析服務的時候,您可能會發現需要將參數傳遞給Autofac。 (如果您在註冊時知道值,則可以在註冊中提供它們,詳細見上篇。)Resolve()方法使用可變長度的參數列表在註冊時接受相同的參數類型

3.1 可用參數類型

Autofac提供了幾種不同的參數匹配策略:

  • NamedParameter - 按名稱匹配目標參數

  • TypedParameter - 按類型匹配目標參數(需要精確類型匹配)

  • ResolvedParameter - 靈活的參數匹配

NamedParameter和TypedParameter只能提供常量值。

ResolvedParameter可以用作提供從容器動態檢索的值的方法,例如。 通過名稱解析服務。

3.2 帶反射組件的參數

當您解析基於反射的組件時,類型的構造函數可能需要您需要根據運行時值指定的參數,這在註冊時不可用。 您可以在Resolve()方法調用中使用一個參數來提供該值。

  假設您有一個配置讀取器,需要傳遞一個配置部分名稱:

1  public class ConfigReader : IConfigReader
2     {
3         public ConfigReader(string configSectionName)
4         {
5             // 存儲配置的節點名稱
6         }
7 
8         // 讀取基於節點名稱的配置
9     }

  您可以將參數傳遞給Resolve()調用,如下所示:

//註冊
 builder.RegisterType<ConfigReader>().As<IConfigReader>();
//解析
 var reader = scope.Resolve<IConfigReader>(new NamedParameter("configSectionName", "mySectionName"));

  如果您有多個參數,只需通過Resolve()方法將它們全部傳遞:

 var service = scope.Resolve<AnotherService>(
                new NamedParameter("id", "service-identifier"),
                new TypedParameter(typeof(Guid), Guid.NewGuid()),
                new ResolvedParameter(
                  (pi, ctx) => pi.ParameterType == typeof(ILog) && pi.Name == "logger",
                  (pi, ctx) => LogManager.GetLogger("service")));

3.3 具有Lambda表達式組件的參數

  使用lambda表達式組件註冊,您需要在lambda表達式中添加參數處理,因此當Resolve()調用傳入時,可以利用它們。

在組件註冊表達式中,您可以通過更改用於註冊的代理簽名來使用傳入參數。 而不是僅僅使用IComponentContext參數,而是接收一個IComponentContext和一個IEnumerable <Parameter>:

相關實例:

   // c 是當前組件上下文
   // p 是IEnumerable<Parameter>參數集合
   builder.Register((c, p) =>new ConfigReader(p.Named<string>("configSectionName")))
          .As<IConfigReader>();

現在,當您解析IConfigReader時,您的lambda將使用傳遞的參數:

//解析時傳參
var reader = scope.Resolve<IConfigReader>(new NamedParameter("configSectionName", "sectionName"));

參考文章:

  1、https://blog.csdn.net/chiyueqi/article/details/52446569

  2、http://www.yuanjiaocheng.net/Autofac/register-parameters.html

IoC之AutoFac(二)——解析服務