使用AutoFac自动绑定接口

20 c# asp.net asp.net-mvc autofac

我有一些像UserQuery,CustomerQuery分别实现IUserQuery,ICustomerQuery等接口的类.在我的绑定配置中,我需要使用相应的查询绑定每个接口:

builder.RegisterType<UserQuery>().As<IUserQuery>().InstancePerRequest();
builder.RegisterType<CustomerQuery>().As<ICustomerQuery>().InstancePerRequest();
Run Code Online (Sandbox Code Playgroud)

这工作得很好,但我想知道是否有办法建立一个基于约定的绑定代替绑定每个单一的classe XXX [查询] - > [I] XXX [查询].

我正在使用AutoFac作为我的DI容器.

gus*_*ico 30

我不是AutoFac有经验的用户.但经过一些研究后,我们成功地测试了以下代码:

var assembly = Assembly.GetExecutingAssembly();

builder
    .RegisterAssemblyTypes(assembly)
    .AssignableTo<IQuery>()
    .AsImplementedInterfaces()
    .InstancePerRequest();
Run Code Online (Sandbox Code Playgroud)

上面的IQuery接口只是一个标记接口,应该从您拥有的每个查询接口继承.使用你的例子:

接口

IUserQuery: IQuery
ICustomerQuery: IQuery
Run Code Online (Sandbox Code Playgroud)

UserQuery: IUserQuery
CustomerQuery: CustomerQuery
Run Code Online (Sandbox Code Playgroud)

  • @Matt是的,有一个空的标记界面是常见的.因此,如果您拥有IUserQuery和ICustomerQuery,您可以并且绝对应该使用标记接口来使容器注册更清晰.但有时,当您实现无法更改的第三方接口时,您无法使用此选项. (3认同)
  • 请注意,如果您使用 FxCop,他们会在标记界面上锁定您。他们会建议使用属性(我也这样做),以便元数据(您正在查询的内容)保留元数据。您可以使用 .Where() 子句来查询自定义属性,而不是使用AssignableTo&lt;T&gt;。 (2认同)

nem*_*esv 11

您需要使用Autofac 的装配扫描功能.

如果您的接口或您的实现共享基类(例如QueryBase)或基本接口(例如IQuery),那么您可以使用conince方法进行注册,如: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)));
Run Code Online (Sandbox Code Playgroud)

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

  • 很好的信息,但条件`单(i => i.Name.EndsWith(t.Name))`允许将`Sample`注册为`ISomethingSample`.更确切地说,只允许`ISample`,类似于`Single(i => i.Name =="I"+ t.Name)`或`Single(i => i.Name.Length == t.Name .Length + 1 && i.Name.EndsWith(t.Name))`会起作用. (4认同)