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

閱讀目錄html

 


一 Resolve方法

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

複製代碼
 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。函數

二 TryResolve和ResolveOptional方法

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

複製代碼
 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                 }
複製代碼

三 解析服務時傳參

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

3.1 可用參數類型

Autofac提供了幾種不一樣的參數匹配策略:代理

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

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

  • ResolvedParameter - 靈活的參數匹配blog

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"));
相關文章
相關標籤/搜索