25

我有一些类,如 UserQuery、CustomerQuery 分别实现 IUserQuery、ICustomerQuery 等接口。在我的绑定配置中,我需要将每个接口与相应的查询绑定:

builder.RegisterType<UserQuery>().As<IUserQuery>().InstancePerRequest();
builder.RegisterType<CustomerQuery>().As<ICustomerQuery>().InstancePerRequest();

这工作得很好,但我想知道是否有一种方法可以进行基于约定的绑定来代替绑定每个类 XXX[Query] -> [I]XXX[Query]。

我使用 AutoFac 作为我的 DI 容器。

4

3 回答 3

36

我不是 AutoFac 经验丰富的用户。然而,经过一些研究,成功地测试了下面的代码:

var assembly = Assembly.GetExecutingAssembly();

builder
    .RegisterAssemblyTypes(assembly)
    .AssignableTo<IQuery>()
    .AsImplementedInterfaces()
    .InstancePerRequest();

上面的 IQuery 接口只是一个标签接口,应该从您拥有的每个查询接口继承。使用您的示例:

接口

IUserQuery: IQuery
ICustomerQuery: IQuery

课程

UserQuery: IUserQuery
CustomerQuery: CustomerQuery
于 2013-01-30T12:27:37.297 回答
11

您需要使用 Autofac 的程序集扫描功能

如果您的接口或您的实现共享基类(例如QueryBase)或基接口(例如IQuery),那么您可以使用令人信服的方法进行注册,例如:AssignableTo<>等。请参阅gustavodidomenico 的答案。

但是,有时您无法拥有通用的基接口/类,在这种情况下,您可以使用Where可以拥有任何自定义逻辑的方法来检测应该注册哪些类以及如何注册。

在这种情况下,您的注册大致如下所示:

builder.RegisterAssemblyTypes(yourAssembly)
       .Where(t => t.IsClass && t.Name.EndsWith("Query"))
       .As(t => t.GetInterfaces().Single(i => i.Name.EndsWith(t.Name)));

它将注册名称以"Query"匹配接口结尾的给定程序集的所有类型,因此它将注册SomeNiceQuery到接口ISomeNiceQuery

于 2013-01-30T12:26:46.397 回答
0

或者,您可以将每种类型注册为它的第一个实现接口或它自己的接口。

builder.RegisterAssemblyTypes(new[] { Assembly.GetAssembly(typeof(IUserQuery))})
        .Where(x=> x.IsClass && x.Name.EndsWith("Query"))
        .As(t => t.GetInterfaces().Any() ? t.GetInterfaces()[0] : t);
于 2016-11-22T10:06:16.367 回答