C# AutoFac 基本用法

169 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

依赖注入

依赖注入,是指类之间依赖关系,通过注入的方式而不是通过使用 new 一个对象然后使用。

Class AObj {
    public void do(){
      BObj b = new BObj();
      b.do();
    }
}

// 通过构造函数注入
class AObj{
    BObj b;
   public AObj(BObj b){
    this.b=b;
   }
   public void do(){   
      b.do();
    }
}

AObj 类中使用了 BObj 类,一般情况下,在AObj 类的方法Do 使用了 BObj 类,基本都是通过 new 一个对象然后使用。如果有多个类就可能需要实例化多次,不仅维护不方便而且也会浪费资源不断的去实例化。

以上代码通过使用构造函数注入的方式解决了对依赖的类的使用,这样就没不用每次调用一次方法就实例化一次。依赖注入的方式还有其他种,比如:方法属性注入,属性 set 方法注入,接口注入。

AutoFac

现有很多实现依赖注入的第三方类库,可以很好帮助你实现对象之间的解耦工作。Autofac 是比较流行的 IOC 容器。其支持属性注入和方法注入,还支持 AOP 功能。更多详细的介绍和使用可查看官网

基本用法

//创建一个容器建造者
ContainerBuilder cb = new ContainerBuilder();
// 注册普通类
cb.RegisterType<ClassA>();
// build下得到容器
IContainer cc = cb.Builder();
//基于容器获取对象实例
ClassA aobj = cc.Resolve<ClassA>();

注册类型有三种:

// 第一种:注册普通类
cb.RegisterType<ClassA>();
// 第二种:注册抽象和实现
cb.Register<ClassA>().As<IA>()
// 第三种:直接注册实例
cb.ResgiterInstance(new AClass())
// 第四种:注册程序集
builder.RegisterAssemblyTypes(classAssembly);

作为一个项目的 IOC 支持,我使用的时候是使用程序集的方式进行注册。因为它支持以接口的方式进行注册 AsImplementedInterfaces(),顶层调用只需关注接口无需关注具体实现,很好的体现解耦。所以将接口注册到IOC 中。

程序集的方式还支持条件类型的注册 Where() ,可以过滤掉不需要依赖的注入的类。

cb.RegisterAssemblyTypes(程序集数组),程序集必须是public的
.AsImplementedInterfaces():表示注册的类型,以接口的方式注册
.PropertiesAutowired():支持属性注入
.Where:满足条件类型注册

对象的声明周期

注册到 IOC 中的类,还可以根据属性指定创建出来的对象的声明周期:

  • 每次获取都是新的实例 ,使用 InstancePerDependency(),其也是 Autofac 的默认设置。
  • 同一个进程内是同一个实例,就是单例的。使用 SingInstance() 方法
  • 同一个作用域内是同一个实例,使用 InstancePerLifetimeScope()方法
  • 在作用域范围里面,同一个作用域下面的对象是同一个,在作用域范围外无法创建实例,使用InstancePerMatchingLifetimeScope()方法
  • 一次请求同一个对象 InstancePerRequest方法

总结

依赖注入可以很好的对类进行解耦。松耦合,方便开发测试。在软件设计原理说到:“上层模块不应依赖于底层模块,应当依赖于抽象,而不应依赖于细节”。其实就是在说解耦,顶层模块通过接口得到对应的具体实现,而上层无需关心底下的具体实现的东西,只需知道该接口就可以。