在简单注入器版本 3 中注册泛型类型



我一直在遵循这里非常有用的答案,使用 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 中发生类型为"System.InvalidOperationException"的异常.dll但未在用户代码中处理

其他信息:配置无效。为类型创建实例失败。类型为 TestService 的构造函数包含名称为"calls"和未注册的类型IRepository<Call>的参数。请确保IRepository<Call>已注册,或更改测试服务的构造函数。但是,IEnumerable<IRepository<Call>>有一个注册;你的意思是依靠IEnumerable<IRepository<Call>>吗?

我也试过

container.RegisterCollection<IRepository>(new [] {typeof(IRepository)});
container.RegisterCollection(typeof(IRepository), new[] {typeof(IRepository)});

我的目的是获得一个 GenericRepository 的实例,因为它暗示了 IRepository,如上面链接中的答案所示。

您收到的异常消息实际上很清楚(或者至少对我来说):

请确保IRepository<Call>已注册,或更改测试服务的构造函数。但是,有注册 IEnumerable<IRepository<Call>> ;你的意思是依靠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 });

这确保了一对一的映射,并在意外出现同一封闭泛型类型的更多实现时将引发异常。

最新更新