我有一些像UserQuery,CustomerQuery分别实现IUserQuery,ICustomerQuery等接口的类。在我的绑定配置中,我需要使用相应的查询绑定每个接口:
builder.RegisterType<UserQuery>().As<IUserQuery>().InstancePerRequest();
builder.RegisterType<CustomerQuery>().As<ICustomerQuery>().InstancePerRequest();
这工作得很好,但我想知道是否有办法制作基于约定的绑定来代替绑定每个单独的classe XXX [查询] - &gt; [I] XXX [查询]。
我正在使用AutoFac作为我的DI容器。
答案 0 :(得分:30)
我不是AutoFac有经验的用户。然而,经过一些研究,测试下面的代码成功:
var assembly = Assembly.GetExecutingAssembly();
builder
.RegisterAssemblyTypes(assembly)
.AssignableTo<IQuery>()
.AsImplementedInterfaces()
.InstancePerRequest();
上面的IQuery接口只是一个标记接口,应该从您拥有的每个查询接口继承。使用您的示例:
接口
IUserQuery: IQuery
ICustomerQuery: IQuery
类
UserQuery: IUserQuery
CustomerQuery: CustomerQuery
答案 1 :(得分:10)
您需要使用Autofac的assembly scanning feature。
如果您的接口或您的实现正在共享基类(例如QueryBase
)或基本接口(例如IQuery
),那么您可以使用conince方法进行注册,如:{{1} }等,请参阅gustavodidomenico's回答。
但是,有时您不能拥有公共基本接口/类,在这种情况下,您可以使用AssignableTo<>
方法,您可以使用任何自定义逻辑来检测应注册哪些类以及如何注册。
在这种情况下,您的注册大致应如下所示:
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
答案 2 :(得分: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);