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

 public static void RegisterAutofac()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()); #region IOC注册区域 //Admin
builder.RegisterType<AdminService>().As<IAdminService>().InstancePerHttpRequest(); #endregion
// then
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); }

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

RegisterAutofac方法所在类的臃肿,且不符合类的职责单一原则。

  为此我想到,能否根据注册类型,将IOC注册区域部分提取到不同的类中实现,将如这些类拥有一个共同的接口,不是就可以根据接口反射出获取这些类了吗?
  
首先,定义反射类。用于获取继承接口的类型
  public class ContainerTypeFinder : ITypeFinder
{ public IList<Assembly> GetAssemblies()
{
//由于注册文件可能分布在不同类库,为此我们获取所有程序集,而不是当前程序集
return AppDomain.CurrentDomain.GetAssemblies(); } public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom)
{
var list = new List<Type>();
foreach (var item in GetAssemblies())
{
var typesToRegister = item.GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.GetInterface(assignTypeFrom.Name) == assignTypeFrom)
;
if (typesToRegister.Count() > )
{
list.AddRange(typesToRegister);
}
}
return list;
}
}

  然后,就是将IOC注册区域移除到类当中

  public interface IDependencyRegistrar
{
void Register(ContainerBuilder builder); int Order { get; }
} public class DependencyRegistrar : IDependencyRegistrar
{
public void Register(ContainerBuilder builder)
{
builder.RegisterType<EfRepository<Core.Domain.Customer.Customer>>().As<IRepository<Core.Domain.Customer.Customer>>().InstancePerHttpRequest();
} public int Order
{
get { return ; }
}
}
  IDependencyRegistrar就是我们上面所说的接口,ContainerTypeFinder类当中的FindClassesOfType()方法会搜寻所有实现该接口的类。实现的注册工作在Register()方法中完成。
接着,封装一个方法完成所有的Autofac注册工作,同时便于在Global中调用:
 public static void InitContainer()
{
//autofac 容器
ContainerBuilder builder = new ContainerBuilder();
//注册所有控制器
builder.RegisterControllers(_typeFinder.GetAssemblies().ToArray()); #region 反射 核心
//通过反射得到继承IDependencyRegistrar该接口的类成员
var types = _typeFinder.FindClassesOfType(typeof(IDependencyRegistrar));
var drInstances = new List<IDependencyRegistrar>();
//创建实例
foreach (var drType in types)
drInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType));
//sort
drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList();
//执行Register方法
foreach (var dependencyRegistrar in drInstances)
dependencyRegistrar.Register(builder);
#endregion //then
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

最后在Global文件Application_Start()方法中调用上述方法

ContainerManager.InitContainer();


 

												

【反射】——Autofac 类型注册的更多相关文章

  1. Autofac全面解析系列(版本:3.5) – [使用篇(推荐篇):1.类型注册]

    前言 Autofac Autofac是一套高效的依赖注入框架. Autofac官方网站:http://autofac.org/ Autofac在Github上的开源项目:https://github. ...

  2. IoC容器Autofac正篇之类型注册(四)

    Autofac类型注册 类型注册简单的从字面去理解就可以了,不必复杂化,只是注册的手段比较丰富. (一)类型/泛型注册 builder.RegisterType<Class1>(); 这种 ...

  3. IoC容器Autofac正篇之类型注册(五)

    Autofac类型注册 类型注册简单的从字面去理解就可以了,不必复杂化,只是注册的手段比较丰富. (一)类型/泛型注册 builder.RegisterType<Class1>(); 这种 ...

  4. Autofac之类型注册

    本次主要学习一下Autofac中实现类型注册的几种方式,这里并不打算一开始就从基于接口开发的服务关联切入,而是先从一个简单的类型注册来学起,虽然实际开发中可能不会这么做,但是个人感觉从这里学起理解能能 ...

  5. [翻译] Autofac 中注册的概念

    原文链接:http://docs.autofac.org/en/latest/register/registration.html 所谓注册组件,是指创建 ContainerBuilder 的实例,并 ...

  6. c#反射机制学习和利用反射获取类型信息

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  7. EF6CodeFirst+MVC5+Autofac泛型注册 入门实例

    贴一个EF6 CodeFirst模式结合MVC5和Autofac(泛型注册)的一个入门实例 网上类似的例子实在太少,最近自己也有用到这一块的知识,总结了一下,不要让后人踩了自己踩过的坑. 1:新建三个 ...

  8. Go语言反射之类型反射

    1 概述 类似于 Java,Go 语言也支持反射.支持反射的语言可以在运行时对程序进行访问和修改.反射的原理是在程序编译期将反射信息(如类型信息.结构体信息等)整合到程序中,并给提供给程序访问反射信息 ...

  9. autofac如何注册静态方法里的接口对象

    标题可能是不准确的,因为我不知道如何描述.不知道的原因,是对依赖注入一知半解. Autofac可以自动注册对象实例到接口,人所尽知.而在asp.net mvc中,这个实例化的工作,通常在每个控制器的构 ...

随机推荐

  1. Linux ssh exit,启动的后台进程不会停止

    一般情况下,想要通过终端长时间运行任务,需要使用nohup 或者 screen,如果不使用会怎么样呢?来测试一下   描述: 场景1:ssh登录机器,通过添加(&),启动任务到后台,通过exi ...

  2. (四)、 nodejs中Async详解之一:流程控制

    为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...

  3. ios网络:应用一个请求的7个步骤

    Splitting big tasks into small tasks is often one of the best ways to solve a problem. Thus, in the ...

  4. Windows Server 2008 R2 密码破解

    Win 2008 Server 忘记密码怎么办,不能像Win7/8/XP 那样用PE破解就只有这种方法了1.首先,把Windows 2008 的镜像放进去光驱我们用光驱启动     2. 这时候按下S ...

  5. DataGridView 控件用法(可能不是很全面,因为这是自己常常用到的一些小总结):

    一.DataGridView属性设置 1.我们单击选中行的时候,默认是选择一个单元格,不能选择一整行,我们只需设置DataGridView的属性SelectionMode为FullRowSelect ...

  6. 在Windows下Mysql如何重置root用户密码

    原文链接:http://www.feeldesignstudio.com/2013/05/windows-mysql-root-password-reset 网上的很多在Windows下重置root用 ...

  7. 16)JAVA实现回调(Android,Swing中各类listener的实现)

           熟悉MS-Windows和X Windows事件驱动设计模式的开发人员,通常是把一个方法的指针传递给事件源,当某一事件发生时来调用这个方法(也称为"回调").Java ...

  8. DOS下无法调出中文输入法-Solved

    From:http://www.cnblogs.com/killerlegend/p/3750542.html Author:KillerLegend Date:2014.5.24 DOS下无法打开中 ...

  9. 一个表格说明RelativeLayout中的几个重要属性【Written By KillerLegend】

      RelativeLayout中几种布局属性的说明 无 无 无 无

  10. Firebird 修改表名

    UPDATE RDB$RELATIONS SET  RDB$RELATION_NAME='NEWNAME' where RDB$RELATION_NAME='OLDNAME'; UPDATE RDB$ ...