zoukankan      html  css  js  c++  java
  • 【反射】——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(); 


     
    
    
    
    
    
  • 相关阅读:
    分组声明
    描述项目的典型用户与场景
    用户调研
    10-11-12
    Sprint--5.21
    Cosplay之孩子的妈咪
    作业5.1之5.2
    51nod 1393 1393 0和1相等串
    51nod 1090 3个数和为0(排序+二分)
    51nod 1095 Anigram单词(map的使用)
  • 原文地址:https://www.cnblogs.com/Jnw-qianxi/p/3756969.html
Copyright © 2011-2022 走看看