Autofac入门之注册

这里主要学习一下Autofac如何实现控制反转与依赖注入

Autofac使用流程

  • 按照Ioc(控制反转)的思想构建你的应用
  • 添加Autofac引用
  • 创建ContainerBuilder
  • 注册组件
  • 创建容器,将其保存以备后续使用
  • 应用程序运行阶段
  • 从容器中创建一个生命周期
  • 在此生命周期作用域内解析组件实例

nuget添加Autofac引用

测试代码

class SqlDal
{
    public void Add()
    {
        Console.WriteLine("向数据库写入一条数据");
    }
}

创建容器

var builder = new ContainerBuilder();

类型注册/泛型注册:注册的类型必须在当前项目或被当前项目引用,因为使用泛型,必须类型明确

//将SqlDal类注册到容器中
builder.RegisterType<SqlDal>();
//通过Resolve()方法获取注册类型的实例,不推荐这种方式获取,这里的代码只作为测试
using (var container = builder.Build())
{               
    var sqlDal = container.Resolve<SqlDal>();
    sqlDal.Add();
}

程序集批量注册:类型注册中提到了通过扫描程序集,来获取部分类型进行注册。Autofac对此提供了一个方便的方式,可以直接通过程序集来筛选类型注册

//获取当前应用程序加载程序集(C/S应用中使用)
var assembly = Assembly.GetExecutingAssembly();
//注册所有程序集类定义的非静态类型
builder.RegisterAssemblyTypes(assembly);

 程序集过滤后批量注册:上面的方式达到了批量的效果,但是通常并不需要把所有的类型都进行注册,所以Autofac提供了几种过滤方式

builder.RegisterAssemblyTypes(assembly).Where(type => type.Namespace.Equals("CSharp.Tests.框架学习"));

 排除指定类型的注册:Except

  builder.RegisterAssemblyTypes(assembly).Where(type => type.Namespace.Contains("CSharp.Tests")).Except<CSharp.Tests.设计思想.SqlDal>();

扫描二维码关注公众号,回复: 5966339 查看本文章

被注册的类型需要在指定类的命名空间中

var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly).InNamespaceOf
<AutofacTest>();

lambda表达式注册:之前的方式都是通过类型进行直接注册的,这种注册方式,在获取时,会直接通过构造函数new出对象,不会做更多的操作。有时我们希望能够在获取对象时能够自动的做更多的事情时,我们可以通过Lambda注册来解决,在lambda表达式中可以做很多事,包括一些属性注入、方法注入、条件判断等等

class SqlDal
{
    public string Str { get; set; }

    public void Add()
    {
        Console.WriteLine("向SqlServer数据库写入一条数据,Str={0}", Str);
    }
}
builder.Register(type =>
{
    //通过lambda表达式注册时添加属性值
    var sqlDal = new SqlDal();         
    sqlDal.Str = "Test";
    return sqlDal;
});

实例注册:通过RegisterInstance进行实例注册,进行实例注册时,需要注意,实例注册可以作为一种单例注册的方式,也就是在后面通过Autofac获取SqlDal对象时,获取到的是注册时的那个对象。并且,如果一个在某处修改了该对象,其他地方再获取时,获取到的就是修改后的对象

builder.RegisterInstance(new SqlDal());
using (var container = builder.Build())
{
    var sqlDal = container.Resolve<SqlDal>();
    sqlDal.Add();
}

Module注册:在日常开发中,可能不同开发会负责不同的模块进行单独开发。在开发过程中,不同模块不同开发可能都有自己的类型需要注册到autofac中,但是如果每个人在注册时,都去修改一个指定地方的代码,这在进行代码合并时,是令人痛苦的。更好的方式是,每个开发不同的模块都有自己指定的类型注册区域,这样,在代码合并时,会减少很多代码冲突

class SqlModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<SqlDal>();
    }
}
class MySqlModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<MySqlDal>();
    }
}
builder.RegisterModule<SqlModule>();            
builder.RegisterModule<MySqlModule>();
using (var container = builder.Build())
{
    var sqldal = container.Resolve<SqlDal>();
    sqldal.Add();
    var mysqldal = container.Resolve<MySqlDal>();
    mysqldal.Add();
}

上述代码中,有两个继承自Module类的类:SqlModule、MySqlModule,这两个类型重写了父类的Load方法,并在load方法中,分别注册了SqlDal与MySqlDal类型。然后在主程序中,通过RegisterModule对Module进行注册。

通过这种方式,不同的开发就可以各自创建一个类继承自Module,然后重写Load方法,在Load方法进行自己的类型注册,最后再进行Module的统一注册(这里还可以通过自定义实现了IModule接口的类型,然后在RegisterModule时传入来达到同样的效果并且功能也更多)

程序集Module注册

Module注册,为多人开发提供了一种方便的注册方式,但是也可以发现,这种方式,还是会需要手动注册Module,如果Module过多,Module注册代码也会显得多而杂,当然,可以通过人工管理来控制Module的量。但是Autofac还提供了一种更方便的方式,并且,对于类似Orchard的模块开发(子模块与主模块无引用关系,通过程序集加载方式来加载子模块)或是插件开发,我们没办法通过Registerodule来注册无直接引用关系的Module

var assembly = Assembly.GetExecutingAssembly();
//注册assembly程序集中所有实现了IModule接口的类型(多层继承也算),这样只需要取出所有程序集,然后通过RegisterAssemblyModules进行一次性注册,就可以自动注册所有Module了
builder.RegisterAssemblyModules(assembly);            
builder.RegisterAssemblyModules<SqlModule>(assembly);//指定泛型类型只注册assembly程序集中继承自SqlModule的Module 

 好文推荐:https://www.cnblogs.com/ancupofcoffee/p/5007649.html

猜你喜欢

转载自www.cnblogs.com/GnailGnepGnaw/p/10747541.html