【反射】——Autofac 类型注册

  Autofac是.net界一款轻量化的IOC组件,使用Autofac可以帮助完成代码中很多依赖注入工作。在以前文章中,介绍过Autofac的配置过程(http://www.cnblogs.com/Jnw-qianxi/p/3450344.html),在我以往的配置过程中,接口与接口的实现类的注册在一个静态方法RegisterAutofac中实现:

 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注册区域中会不断添加新的注册,不同区域,不同模块的类型注册都会在这进行(数据仓储层,业务逻辑层,基础设施层等等不同层次的类型注册都要在此方法中进行),同时系统不同开发人员都需要维护该方法,这样带来

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注册区域移除到类当中

 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()方法中调用上述方法

 1 ContainerManager.InitContainer(); 


 

 

 
 
  
 
  

 

你可能感兴趣的:(auto)