在SimpleInjector版本3中注册通用类型 [英] Register generic types in SimpleInjector Version 3
问题描述
我一直在关注非常有用的答案此处使用SimpleInjector DI动态地组织我的工作单元和存储库。
I've been following the very helpful answer here to organise my unit of work and repositories dynamically using SimpleInjector DI.
使用下面的测试服务:
public class TestService
{
public TestService(IRepository<Call> calls){}
}
在控制器中:
public class TestingController : Controller
{
private readonly IUnitOfWork _unitOfWork ;
public TestingController(IUnitOfWork unitOfWork, TestService testService)
{
_unitOfWork = unitOfWork;
}
}
和引导程序:
public static class BootStrapper
{
public static void ConfigureWeb(Container container)
{
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Options.ConstructorResolutionBehavior = new GreediestConstructorBehavior();
container.Register<DbContext, OCISContext>(Lifestyle.Scoped);
container.Register<ApplicationUserManager>(Lifestyle.Scoped);
container.Register<ApplicationSignInManager>(Lifestyle.Scoped);
container.Register<IAuthenticationManager>(() =>
AdvancedExtensions.IsVerifying(container)
? new OwinContext(new Dictionary<string, object>()).Authentication
: HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
container.Register<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(Lifestyle.Scoped);
container.Register<IUnitOfWork, UnitOfWork.UnitOfWork>(Lifestyle.Scoped);
container.RegisterCollection(typeof(IRepository<>), typeof(IRepository<>).Assembly);
container.Register<TestService>(Lifestyle.Scoped);
}
我收到错误:
SimpleInjector.dll中发生类型'System.InvalidOperationException'的异常,但未在用户代码中处理
An exception of type 'System.InvalidOperationException' occurred in SimpleInjector.dll but was not handled in user code
其他信息:配置无效。创建类型为TestService的实例失败。类型为TestService的构造函数包含名称为 calls的参数,类型为未注册的 IRepository< Call>
。请确保已注册 IRepository< Call>
,或更改TestService的构造函数。但是,有一个 IEnumerable< IRepository< Call>>
的注册;您是要依靠 IEnumerable< IRepository< Call>>
吗?
Additional information: The configuration is invalid. Creating the instance for type TestService failed. The constructor of type TestService contains the parameter with name 'calls' and type IRepository<Call>
that is not registered. Please ensure IRepository<Call>
is registered, or change the constructor of TestService. There is, however, a registration for IEnumerable<IRepository<Call>>
; Did you mean to depend on IEnumerable<IRepository<Call>>
?
我已经还尝试过
container.RegisterCollection<IRepository>(new [] {typeof(IRepository)});
container.RegisterCollection(typeof(IRepository), new[] {typeof(IRepository)});
我的意图是获取GenericRepository的实例,因为它可以实现IRepository,如上面链接中的答案所示。
My intention is to get an instance of GenericRepository as this implents IRepository as shown in the answer in the link above.
推荐答案
您收到的异常消息实际上非常清楚(或者至少对我而言):
The exception message you get is actually pretty clear (or at least, to me):
请确保已注册
IRepository< Call>
,或更改TestService的构造函数。但是,有一个IEnumerable< IRepository< Call>>
的注册;您是要依靠IEnumerable< IRepository< Call>>
吗?
Please ensure
IRepository<Call>
is registered, or change the constructor of TestService. There is, however, a registration forIEnumerable<IRepository<Call>>
; Did you mean to depend onIEnumerable<IRepository<Call>>
?
换句话说,您进行了以下注册:
In other words, you made the following registration:
container.RegisterCollection(typeof(IRepository<>), typeof(IRepository<>).Assembly);
RegisterCollection
表示可以将注册解析为采集。但是,您的 TestService
取决于 IRepository< Call>
而不是 IEnumerable< IRepository< Call>> ;
。
RegisterCollection
means that registrations can be resolved as collection. Your TestService
however depends on IRepository<Call>
instead of IEnumerable<IRepository<Call>>
.
因为我认为您的应用程序不太可能将多个实现用于 IRepository< Call>
同时,注册收藏可能不是您想要的;通用 IRepository< T>
接口的封闭版本与实现之间可能存在一对一的映射。
Since I think it is unlikely that your application will use multiple implementations for IRepository<Call>
at the same time, registration of collections is probably not what you want; there is likely a one-to-one mapping between a closed version of the generic IRepository<T>
interface and an implementation.
因此,请按以下方式进行注册:
So instead, make the registration as follows:
container.Register(typeof(IRepository<>), new[] { typeof(IRepository<>).Assembly });
这可确保一对一映射,并在意外地有更多实现的情况下引发异常对于相同的封闭通用类型。
This ensures the one-to-one mapping and will throw an exception in case there accidentally are more implementations for the same closed generic type.
这篇关于在SimpleInjector版本3中注册通用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!