【反射】——Autofac 類型註冊

  Autofac是.net界一款輕量化的IOC組件,使用Autofac能夠幫助完成代碼中不少依賴注入工做。在之前文章中,介紹過Autofac的配置過程(http://www.cnblogs.com/Jnw-qianxi/p/3450344.html),在我以往的配置過程當中,接口與接口的實現類的註冊在一個靜態方法RegisterAutofac中實現:html

 1 public static void RegisterAutofac()
 2         {
 3             ContainerBuilder builder = new ContainerBuilder();
 4             builder.RegisterControllers(Assembly.GetExecutingAssembly());
 5 
 6             #region IOC註冊區域
 7         
 8            
 9             //Admin
10             builder.RegisterType<AdminService>().As<IAdminService>().InstancePerHttpRequest();
11 
12         
13             #endregion
14             // then
15             var container = builder.Build();
16             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
17           
18         }

    隨着系統開發的進行,IOC註冊區域中會不斷添加新的註冊,不一樣區域,不一樣模塊的類型註冊都會在這進行(數據倉儲層,業務邏輯層,基礎設施層等等不一樣層次的類型註冊都要在此方法中進行),同時系統不一樣開發人員都須要維護該方法,這樣帶來ui

RegisterAutofac方法所在類的臃腫,且不符合類的職責單一原則。

  爲此我想到,可否
根據註冊類型,將IOC註冊區域部分提取到不一樣的類中實現,將如這些類擁有一個共同的接口,不是就能夠根據接口反射出獲取這些類了嗎?
  
首先,定義反射類。用於獲取繼承接口的類型
 1  public class ContainerTypeFinder : ITypeFinder
 2     {
 3 
 4         public IList<Assembly> GetAssemblies()
 5         {
 6             //因爲註冊文件可能分佈在不一樣類庫,爲此咱們獲取全部程序集,而不是當前程序集
 7             return AppDomain.CurrentDomain.GetAssemblies();
 8 
 9         }
10 
11         public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom)
12         {
13             var list = new List<Type>();
14             foreach (var item in GetAssemblies())
15             {
16                 var typesToRegister = item.GetTypes()
17               .Where(type => !String.IsNullOrEmpty(type.Namespace))
18               .Where(type => type.GetInterface(assignTypeFrom.Name) == assignTypeFrom)
19              ;
20                 if (typesToRegister.Count() > 0)
21                 {
22                     list.AddRange(typesToRegister);
23                 }
24             }
25             return list;
26         }
27     }
 

  而後,就是將IOC註冊區域移除到類當中spa

 1  public interface IDependencyRegistrar
 2     {
 3         void Register(ContainerBuilder builder);
 4 
 5         int Order { get; }
 6     }
 7 
 8 
 9  public class DependencyRegistrar : IDependencyRegistrar
10     {
11         public void Register(ContainerBuilder builder)
12         {
13             builder.RegisterType<EfRepository<Core.Domain.Customer.Customer>>().As<IRepository<Core.Domain.Customer.Customer>>().InstancePerHttpRequest();
14         }
15 
16         public int Order
17         {
18             get { return 1; }
19         }
20     }
  IDependencyRegistrar就是咱們上面所說的接口,ContainerTypeFinder類當中的FindClassesOfType()方法會搜尋全部實現該接口的類。實現的註冊工做在Register()方法中完成。
接着,封裝一個方法完成全部的Autofac註冊工做,同時便於在Global中調用:
 1 public static void InitContainer() 
 2         {
 3             //autofac 容器
 4             ContainerBuilder builder = new ContainerBuilder();
 5             //註冊全部控制器
 6             builder.RegisterControllers(_typeFinder.GetAssemblies().ToArray());
 7 
 8             #region 反射 核心
 9             //經過反射獲得繼承IDependencyRegistrar該接口的類成員
10             var types = _typeFinder.FindClassesOfType(typeof(IDependencyRegistrar));
11             var drInstances = new List<IDependencyRegistrar>();
12             //建立實例
13             foreach (var drType in types)
14                 drInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType));
15             //sort
16             drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList();
17             //執行Register方法
18             foreach (var dependencyRegistrar in drInstances)
19                 dependencyRegistrar.Register(builder);
20             #endregion
21 
22             //then
23            var container = builder.Build();
24            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

最後在Global文件Application_Start()方法中調用上述方法.net

 1 ContainerManager.InitContainer(); code

相關文章
相關標籤/搜索