C# 当简单注入器只有一个具体的接口时,如何使其自动解析接口?
目前我有一个webapi控制器,其构造函数如下:C# 当简单注入器只有一个具体的接口时,如何使其自动解析接口?,c#,asp.net-web-api,simple-injector,C#,Asp.net Web Api,Simple Injector,目前我有一个webapi控制器,其构造函数如下: readonly IQueryFactory queryFactory; readonly ICommandFactory commandFactory; public UserBenefitsController( IQueryFactory queryFactory, ICommandFactory commandFactory) { this.queryFactory = queryFactory; th
readonly IQueryFactory queryFactory;
readonly ICommandFactory commandFactory;
public UserBenefitsController(
IQueryFactory queryFactory,
ICommandFactory commandFactory)
{
this.queryFactory = queryFactory;
this.commandFactory = commandFactory;
}
我使用简单的注入器来注册这两种类型
container.RegisterWebApiRequest<IQueryFactory, QueryFactory>();
container.RegisterWebApiRequest<ICommandFactory, CommandFactory>();
container.RegisterWebApiRequest();
container.RegisterWebApiRequest();
但我发现,随着我继续开发我的应用程序,我继续以1:1的比例将大量的isomointerface
解析为isomoconcrete
当WebApiRequest范围内只有一个具体接口时,是否可以告诉simple injector查找接口并自动解决它?您可以使用批处理/自动注册来解决具体实例。 简单喷油器文档对此进行了解释 例如:
ScopedLifestyle scopedLifestyle = new WebApiRequestLifestyle();
var assembly = typeof(YourRepository).Assembly;
var registrations =
from type in assembly.GetExportedTypes()
where type.Namespace == "Acme.YourRepositories"
where type.GetInterfaces().Any()
select new
{
Service = type.GetInterfaces().Single(),
Implementation = type
};
foreach (var reg in registrations)
container.Register(reg.Service, reg.Implementation, scopedLifestyle);
除了Bacardi先生的正确答案(可能更好)之外,您还可以使用未注册的类型解析,使用以下扩展方法来实现这一点:
public static void AutoMap(this Container container, params Assembly[] assemblies) {
container.ResolveUnregisteredType += (s, e) => {
if (e.UnregisteredServiceType.IsInterface && !e.Handled) {
Type[] concreteTypes = (
from assembly in assemblies
from type in assembly.GetTypes()
where !type.IsAbstract && !type.IsGenericType
where e.UnregisteredServiceType.IsAssignableFrom(type)
select type)
.ToArray();
if (concreteTypes.Length == 1) {
e.Register(Lifestyle.Transient.CreateRegistration(concreteTypes[0],
container));
}
}
};
}
您可以按如下方式使用此扩展方法:
container.AutoMap(Assembly.GetExecutingAssembly());
必须对该方法应用一组严格的程序集,仅包含生产程序集。当您应用所有AppDomain程序集时,您会发现它很可能会在集成或单元测试套件中失败,因为这些程序集中很可能存在这些接口的伪实现
不过,我的偏好是尽可能多地进行明确的预先注册,这正是百加得先生所描述的解决方案。这里描述的方法使用“即时”方法,即在第一次解析时开始寻找实现。但是,如果调用container.Verify()
,在大多数情况下都是安全的,尽管调用Verify()可能会成功,但在运行时解析对象图会失败,因为Verify()只会验证配置已知的对象。因此,您必须确保未注册的接口直接或间接地被实际注册的对象引用。因为很容易忽视这一点,我更喜欢巴拉迪先生的方法
但我必须承认,在我工作的应用程序(通常相当大)中,我们只有一些“一对一”的实现。系统中的大多数实现都实现了一个通用接口(如and),我几乎没有理由对这些非通用接口进行批注册。另一方面,Simple Injector使用了
Register
方法。非常好的信息,非常感谢您花时间给出一个替代方案。当我在本节中这样做时,我得到了一个“序列包含多个元素”的异常。我使用了这个问题的第二个答案来解决我的问题。谢谢