Autofac 之二 注册组件程序集扫描注入
author:尹明能 引入国外网站
Registration Concepts(注册概念)
You register components with Autofac by creating a ContainerBuilder
and informing (通知)the builder which components expose which services.
Components can be created via reflection (by registering a specific .NET type or open generic); by providing a ready-made instance (通过提供现成的实例)(an instance of an object you created); or via lambda expression (an anonymous function that executes to instantiate your object). ContainerBuilder
has a family of Register()
methods that allow you to set these up.
Each component exposes one or more services that are wired up using the As()
methods on ContainerBuilder
.
Assembly Scanning(程序集扫描)
Autofac can use conventions(约定) to find and register components in assemblies. You can scan and register individual (单个)types or you can scan specifically for Autofac modules.
Scanning for Types
Otherwise known as convention-driven registration or scanning, Autofac can register a set of types from an assembly according to user-specified rules:
var dataAccess = Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(dataAccess) .Where(t => t.Name.EndsWith("Repository")) .AsImplementedInterfaces();
Each RegisterAssemblyTypes()
call will apply one set of rules only - multiple invocations of RegisterAssemblyTypes()
are necessary if there are multiple different sets of components to register.
Autofac also supports assembly scanning for open generics using RegisterAssemblyOpenGenericTypes()
. This uses the same general (通用的)semantics(语义学) as RegisterAssemblyTypes()
:
Filtering Types(类型筛选)
RegisterAssemblyTypes()
and RegisterAssemblyOpenGenericTypes()
each accept a parameter array of one or more assemblies. By default, all concrete(具体的) classes in the assembly will be registered. This includes internal(内部的) and nested(嵌套的) private classes. You can filter the set of types to register using some provided LINQ-style predicates.
In 4.8.0 a PublicOnly()
extension was added to make data encapsulation(封装) easier. If you only want your public classes registered, use PublicOnly()
:
builder.RegisterAssemblyTypes(asm)
.PublicOnly();
To apply custom filtering to the types that are registered, use the Where()
predicate:
builder.RegisterAssemblyTypes(asm) .Where(t => t.Name.EndsWith("Repository"));
To exclude(排除) types from scanning, use the Except()
predicate:
builder.RegisterAssemblyTypes(asm)
.Except<MyUnwantedType>();
The Except()
predicate also allows you to customize the registration for the specific excluded type:
builder.RegisterAssemblyTypes(asm) .PublicOnly() .Where(t => t.Name.EndsWith("Repository")) .Except<MyUnwantedRepository>();
Specifying Services(指定服务)
The registration syntaxes for RegisterAssemblyTypes()
and RegisterAssemblyOpenGenericTypes()
are a subset (子集)of the registration syntax for single types(单个类型), so methods like As()
all work with assemblies as well(也):
builder.RegisterAssemblyTypes(asm) .Where(t => t.Name.EndsWith("Repository")) .As<IRepository>();
Additional(额外的) overloads(重载) to As() and Named() accept lambda expressions that determine (决定), for a type, which services it will provide:
builder.RegisterAssemblyTypes(asm) .As(t => t.GetInterfaces()[0]);
common conventions:
Method |
Description |
Example |
---|---|---|
|
Register the type as providing all of its public interfaces as services (excluding |
builder.RegisterAssemblyTypes(asm)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
|
|
Register types that are assignable to a closed instance of the open generic type. |
builder.RegisterAssemblyTypes(asm)
.AsClosedTypesOf(typeof(IRepository<>));
|
|
The default: register types as themselves - useful when also overriding the default with another service specification. |
builder.RegisterAssemblyTypes(asm)
.AsImplementedInterfaces()
.AsSelf();
|
Scanning for Modules
Module scanning is performed with the RegisterAssemblyModules()
registration method, which does exactly what its name suggests. It scans through the provided assemblies for Autofac modules, creates instances of the modules, and then registers them with the current container builder.
For example, say the two simple module classes below live in the same assembly and each register a single component:
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>(); } }
The overload of RegisterAssemblyModules()
that does not accept a type parameter will register all classes implementing IModule
found in the provided list of assemblies. In the example below both modules get registered:
var assembly = typeof(AComponent).Assembly; var builder = new ContainerBuilder(); // Registers both modules builder.RegisterAssemblyModules(assembly);
The overload of RegisterAssemblyModules()
with the generic type parameter allows you to specify a base type that the modules must derive from. In the example below only one module is registered because the scanning is restricted:
var assembly = typeof(AComponent).Assembly; var builder = new ContainerBuilder(); // Registers AModule but not BModule builder.RegisterAssemblyModules(typeof(AModule), assembly);
posted on 2022-05-30 17:40 topguntopgun 阅读(188) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人