一、装配扫描
Autofac允许通过常规组装的方式去注册组件(构造方法、实例、lambda表达式等),您可以扫描和注册单个类型,也可以具体的扫描Autofac模块去注册。
1、扫描类型
除了已知的的常见的注册或扫描,autofac也能通过用户指定的规则从程序集中注册一系列的类
如果当前有多个不同系列的组件需要注册的话,每次执行将请求一系列的一对多调用的规则是必要的
var dataAccess = Assembly.GetExecutingAssembly(); // builder.RegisterAssemblyTypes(dataAccess) .Where(t => t.Name.EndsWith("Repository")) .AsImplementedInterfaces();
过滤类型
RegisterAssemblyTypes()接收一个或多个程序集的数组参数,默认情况下,所有程序集里的实体类都会被注册,这包括内部和嵌套的私有类
您可以使用提供的一些LINQ条件过滤要注册的类型集
在4.08版本有一个拓展方法的加入使得数据封装更加简单,如果你仅仅想注册公共类,可以使用:PublicOnly()
builder.RegisterAssemblyTypes(asm)
.PublicOnly();
要对已注册的类型应用自定义筛选,请使用谓词:Where()
builder.RegisterAssemblyTypes(asm) .Where(t => t.Name.EndsWith("Repository"));
要通过浏览排除类型,使用:Except()
builder.RegisterAssemblyTypes(asm)
.Except<MyUnwantedType>();
也可以通过Except()自定义对特定排除类型进行注册:
builder.RegisterAssemblyTypes(asm) .Except<MyCustomizedType>(ct => ct.As<ISpecial>().SingleInstance());
可以使用多个过滤器,在这种情况下,它们将与逻辑AND一起应用
builder.RegisterAssemblyTypes(asm) .PublicOnly() .Where(t => t.Name.EndsWith("Repository")) .Except<MyUnwantedRepository>();
对于RegisterAssemblyTypes()的注册语法是单个类型的注册语法的超集,所以像As()这样的方法也都可以处理程序集
builder.RegisterAssemblyTypes(asm) .Where(t => t.Name.EndsWith("Repository")) .As<IRepository>();
3、实现
1、创建空接口Idenpendency及实现类
//空接口 public interface IDenpendency { }
InterfaceFirst继承Idenpency,DrinkHelper实现InterfaceFirst
//接口InterfaceFirst实现IDenpendency public interface InterfaceFirst : IDenpendency { public void drink(string water); } // 定义InterfaceFirst的实现 public class DrinkHelper : InterfaceFirst { public void drink(string water) { Console.WriteLine("我在喝"+water); } }
InterfaceSecond继承Idenpency,EatHelper实现InterfaceSecond
//接口InterfaceSecond 实现IDenpendency public interface InterfaceSecond : IDenpendency { public void eat(string food); } // 定义InterfaceSecond的实现EatHelper public class EatHelper : InterfaceSecond { public void eat(string food) { Console.WriteLine("我在吃" + food); } }
注册、解析实现
static void Main(string[] args) { //创建一个容器创建者 var builder = new ContainerBuilder(); //使用lambda表达式注册 var dataAccess = Assembly.GetExecutingAssembly(); Type basetype = typeof(IDenpendency); //获取顶级接口类型 builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => basetype.IsAssignableFrom(t) && t.IsClass) //查询继承自顶级接口IDependency的实现类,如果没有这句,则注册所有当前运行环境中接口实现类 .AsImplementedInterfaces().InstancePerLifetimeScope(); var service = builder.Build(); using (var scope = service.BeginLifetimeScope()) { //同时注册了InterfaceFirst、InterfaceSecond的所有实例 var interfaceDao1 = scope.Resolve<InterfaceFirst>(); interfaceDao1.drink("橙汁"); var interfaceDao2 = scope.Resolve<InterfaceSecond>(); interfaceDao2.eat("牛肉"); } }
//执行结果,两个实例都注册成功,方法都能正常执行
//C# 反射方法 IsAssignableFrom bool res = {TypeA}.IsAssignableFrom({TypeB}) ; //如果TypeA和TypeB类型一样则返回true; //如果TypeA是TypeB的父类则返回true; //如果TypeB实现了接口TypeA则返回true;
二、指定服务
RegisterAssemblyTypes()的注册语法是单个类型的注册语法的超集,因此像As()这样的方法也适用于程序集
builder.RegisterAssemblyTypes(asm) .Where(t => t.Name.EndsWith("Repository")) .As<IRepository>();
As()和Named()的附加重载接受lambda表达式,这些表达式确定类型将提供哪些服务:
builder.RegisterAssemblyTypes(asm) .As(t => t.GetInterfaces()[0]);
与普通组件注册一样,对As()的多个调用被添加到一起。 增加了一些额外的注册方法,以便于建立通用协议:
1.AsImplementedInterfaces() 是以接口方式进行注入,注入这些类的所有的公共接口作为服务(除了释放资源)
A:IA
builder.RegisterType<A>().AsImplementedInterfaces(); 使用时用IA,会返回一个A的实例,即将自身的实例进行注入
方法 | 说明 | 例子 |
AsImplementedInterfaces() | 将该类型注册为服务提供他所有的公共接口 |
builder.RegisterAssemblyTypes(asm)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
|
AsClosedTypesOf(open) | 注册可分配给开放泛型类型的具体实例的类型。 |
builder.RegisterAssemblyTypes(asm)
.AsClosedTypesOf(typeof(IRepository<>));
|
AsSelf() | 默认值:将类型注册为它们自用,当另一个服务规范重写默认值时非常有用。 |
builder.RegisterAssemblyTypes(asm)
.AsImplementedInterfaces()
.AsSelf();
|