c# - SimpleInjector - 如何使用 LifetimeScopeLifestyle 注册泛型的多个实现?

标签 c# dependency-injection inversion-of-control simple-injector

在回答 this question 时所以我想不出用 LifetimeScopeLifestyle 的实例注册泛型类型的许多实现的最佳技术。在 SimpleInjector 中。

这种注册形式的推荐方法是这样的:

container.RegisterManyForOpenGeneric(typeof(IRepository<>), 
    typeof(IRepository<>).Assembly);

但这不允许 LifetimeScopeLifestyle 的实例将被传入。

下面是我想出的,但我知道它不够灵活,因为它正在检查任何通用接口(interface),而不是具体的 IRepository<> .谁能告诉我该怎么做?

public static void Configure(Container container)
{
    var lifetimeScope = new LifetimeScopeLifestyle();

    container.Register<IUnitOfWork, UnitOfWork>(lifetimeScope);

    //this query needs improvement
    var registrations =
        from type in typeof(IRepository<>).Assembly.GetExportedTypes()
        where typeof(IRepository).IsAssignableFrom(type)
            && type.IsClass
            && !type.IsAbstract
        from service in type.GetInterfaces()
        where service.IsGenericType
        select new { Service = service, Implementation = type };

    foreach (var registration in registrations)
    {
        container.Register(registration.Service, 
            registration.Implementation, lifetimeScope);
    }
}

最佳答案

TLDR:

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    lifetimeScope, 
    typeof(IRepository<>).Assembly);

首先,您的查询是错误的。应该是:

var registrations =
    from type in
        typeof(IRepository<>).Assembly.GetExportedTypes()
    where !service.IsAbstract
    where !service.IsGenericTypeDefinition
    from @interface in type.GetInterfaces()
    where @interface.IsGenericType
    where @interface.GetGenericTypeDefinition() ==
        typeof(IRepository<>)
    select new { Service = @interface, Impl = type };

其次,该框架包含一个GetTypesToRegister 方法来为您获取这些类型,不包括装饰器类型:

var repositoryTypes =
    OpenGenericBatchRegistrationExtensions.GetTypesToRegister(
        container, typeof(IRepository<>), 
        typeof(IRepository<>).Assembly);

var registrations =
    from type in repositoryTypes
    from @interface in type.GetInterfaces()
    where @interface.IsGenericType
    where @interface.GetGenericTypeDefinition() ==
        typeof(IRepository<>)
    select new { Service = @interface, Impl = type };

但它变得更好了,容器包含一个 RegisterManyForOpenGeneric 方法的重载,该方法采用一个回调委托(delegate),允许您按如下方式进行注册:

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    (service, impls) =>
    {
        container.Register(service, impls.Single(),
            lifetimeScope);
    }, 
    typeof(IRepository<>).Assembly);

但最重要的是,该框架包含接受 LifetimeRegisterManyForOpenGeneric 重载。因此,您可以将注册简化为以下内容:

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    lifetimeScope, 
    typeof(IRepository<>).Assembly);

关于c# - SimpleInjector - 如何使用 LifetimeScopeLifestyle 注册泛型的多个实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16086121/

相关文章:

c# - 您在 C# 代码中如何以及在何处使用断言?

unit-testing - 如何在函数式编程中编写好的单元测试

.net-core - .NET Core 默认依赖注入(inject)与 CaSTLe DynamicProxy

c# - SignalR 阻止 chrome UI?

c# - C#自定义用户控件...右键菜单复制文本(Java开发者学习C#)

c# - EF核心: update database error: relation "Owner" already exists

javascript - 将对象注入(inject)到服务函数中

ios - iOS 中控制反转的框架和静态库有何不同?

c# - 用于小型 .NET 项目的 IoC/DI

java - 为什么 Avalon-Framework 被关闭了?