1

我一直在关注非常有用的答案here,使用SimpleInjector DI动态组织我的工作单元和存储库。在SimpleInjector版本3中注册泛型类型

使用下面的测试服务:

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的实例,因为这implents IRepository如在上面的链接的答案。

+0

请更新您的代码并添加相关代码,以说明您在UnitOfWork中注册存储库的原因。 – Steven

回答

2

你得到的异常消息其实是很清楚的(或至少,对我来说):

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 }); 

这确保了一个对一映射和将引发的情况下,一个异常偶然有用于相同封闭泛型类型多个实现。

+0

非常感谢!它似乎工作,虽然任何想法为什么同一个存储库创建不止一次,所以它试图再次注册UOW,但失败了,因为密钥已经存在于'private readonly Dictionary _repositories ;'? – Ian

+0

所有的不错,我在某个时候添加了'container.Register (Lifestyle.Scoped)',但这是有问题的代码。现在所有的作品都很棒,非常感谢Steven。 – Ian