您的位置:首页 > 其它

Autofac官方文档(六)【注册组件之程序集扫描】

2017-12-07 22:46 232 查看
Autofac
可以使用约定来查找和注册程序集中的组件。 您可以扫描并注册各种类型,也可以专门扫描Autofac模块。

扫描类型

否则称为惯例驱动的注册或扫描,Autofac可以根据用户指定的规则从程序集中注册一组类型:

var dataAccess = Assembly.GetExecutingAssembly();

builder.RegisterAssemblyTypes(dataAccess)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();


每个
RegisterAssemblyTypes()
调用将仅应用一组规则 - 如果要注册多个不同组的组件,则需要多次调用
RegisterAssemblyTypes()


过滤类型

RegisterAssemblyTypes()
接受一个或多个程序集的参数数组。 默认情况下,程序集中的所有公共具体类都将被注册。 您可以使用一些提供的LINQ样式谓词来过滤要注册的类型集。

要筛选已注册的类型,请使用
Where()
谓词:

builder.RegisterAssemblyTypes(asm)
.Where(t => t.Name.EndsWith("Repository"));


要从扫描中排除类型,请使用
Except()
谓词:

builder.RegisterAssemblyTypes(asm)
.Except<MyUnwantedType>();


Except()
谓词还允许您为特定的排除类型自定义注册:

builder.RegisterAssemblyTypes(asm)
.Except<MyCustomisedType>(ct =>
ct.As<ISpecial>().SingleInstance());


可以使用多个过滤器,在这种情况下,它们将被应用逻辑AND。

指定服务

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()
的调用被加在一起。

增加了一些额外的注册方法,以便更容易地建立通用约定:

MethodDescriptionExample
AsImplementedInterfaces()将类型注册为将其所有公共接口提供为服务(不包括IDisposable)builder.RegisterAssemblyTypes(asm).Where(t => t.Name.EndsWith(“Repository”)).AsImplementedInterfaces();
AsClosedTypesOf(open)注册可分配给已打开泛型类型的已关闭实例的类型。.builder.RegisterAssemblyTypes(asm).AsClosedTypesOf(typeof(IRepository<>));
AsSelf()默认值:注册类型为自己的 - 当用另一个服务规范覆盖默认值时也很有用.builder.RegisterAssemblyTypes(asm).AsImplementedInterfaces().AsSelf();

扫描模块

模块扫描是通过
RegisterAssemblyModules()
注册方法来完成的,而注册方法正是其名字所暗示的。 它扫描所提供的Autofac模块的程序集,创建模块的实例,然后将其注册到当前的容器生成器。

例如,假设下面的两个简单模块类存在同一个程序集中,并且每个注册一个组件:

public class AModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c => new AComponent()).As<AComponent>();
}
}

public class BModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c => new BComponent()).As<BComponent>();
}
}


不接受类型参数的
RegisterAssemblyModules()
的重载将注册在提供的程序集列表中找到的实现
IModule
的所有类。 在下面的例子中,两个模块都被注册了:

var assembly = typeof(AComponent).Assembly;
var builder = new ContainerBuilder();

//注册这两个模块
builder.RegisterAssemblyModules(assembly);


RegisterAssemblyModules()
与泛型类型参数的重载允许您指定(模块必须从中派生的)基本类型。 在下面的例子中,只有一个模块被注册,因为扫描受到限制:

var assembly = typeof(AComponent).Assembly;
var builder = new ContainerBuilder();

//注册模块但不包含BModule
builder.RegisterAssemblyModules<AModule>(assembly);


使用Type对象参数的
RegisterAssemblyModules()
的重载与通用类型参数重载类似,但允许您指定可能在运行时确定的类型。 在下面的例子中,只有一个模块被注册,因为扫描受到限制:

var assembly = typeof(AComponent).Assembly;
var builder = new ContainerBuilder();

// 注册模块但不包含BModule
builder.RegisterAssemblyModules(typeof(AModule), assembly);


IIS托管的Web应用程序

在IIS应用程序中使用程序集扫描时,根据程序集位置的不同,可能会遇到一些麻烦。 (这是我们的常见问题之一)

在IIS中托管应用程序时,应用程序首次启动时,所有程序集都加载到
AppDomain
中,但当
AppDomain
被IIS回收时,程序集仅在需要时加载。

为避免此问题,请使用
System.Web.Compilation.BuildManager
上的
GetReferencedAssemblies()
方法来获取引用程序集的列表:

var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();


这将强制引用的程序集立即加载到AppDomain中,使其可用于模块扫描.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: