在 SimpleInjector 版本 3 中注册泛型类型
Register generic types in SimpleInjector Version 3
我一直在关注非常有用的答案 here 以使用 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);
}
我收到错误:
An exception of type 'System.InvalidOperationException' occurred in SimpleInjector.dll but was not handled in user code
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,如上面 link 中的答案所示。
您收到的异常消息实际上非常清楚(或者至少对我而言):
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(typeof(IRepository<>), typeof(IRepository<>).Assembly);
RegisterCollection
表示注册可以解析为集合。然而,您的 TestService
取决于 IRepository<Call>
而不是 IEnumerable<IRepository<Call>>
.
由于我认为您的应用程序不太可能同时使用 IRepository<Call>
的多个实现,因此集合注册可能不是您想要的;通用 IRepository<T>
接口的封闭版本与实现之间可能存在一对一的映射。
因此,请按如下方式进行注册:
container.Register(typeof(IRepository<>), new[] { typeof(IRepository<>).Assembly });
这确保了一对一的映射,并且会抛出异常,以防意外地有相同封闭泛型类型的更多实现。
我一直在关注非常有用的答案 here 以使用 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);
}
我收到错误:
An exception of type 'System.InvalidOperationException' occurred in SimpleInjector.dll but was not handled in user code
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 ensureIRepository<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>>
?
我也试过
container.RegisterCollection<IRepository>(new [] {typeof(IRepository)});
container.RegisterCollection(typeof(IRepository), new[] {typeof(IRepository)});
我的目的是获取 GenericRepository 的实例,因为它实现了 IRepository,如上面 link 中的答案所示。
您收到的异常消息实际上非常清楚(或者至少对我而言):
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>>
?
也就是说,您进行了以下注册:
container.RegisterCollection(typeof(IRepository<>), typeof(IRepository<>).Assembly);
RegisterCollection
表示注册可以解析为集合。然而,您的 TestService
取决于 IRepository<Call>
而不是 IEnumerable<IRepository<Call>>
.
由于我认为您的应用程序不太可能同时使用 IRepository<Call>
的多个实现,因此集合注册可能不是您想要的;通用 IRepository<T>
接口的封闭版本与实现之间可能存在一对一的映射。
因此,请按如下方式进行注册:
container.Register(typeof(IRepository<>), new[] { typeof(IRepository<>).Assembly });
这确保了一对一的映射,并且会抛出异常,以防意外地有相同封闭泛型类型的更多实现。