简体   繁体   English

SimpleInjector - 如何使用LifetimeScopeLifestyle注册许多泛型类型的实现?

[英]SimpleInjector - how to register many implementations of a generic type with LifetimeScopeLifestyle?

While answering this question on SO I couldn't figure out the best technique for registering many implementations of a generic type with an instance of LifetimeScopeLifestyle within SimpleInjector. 在SO上回答这个问题时 ,我无法找到在SimpleInjector中使用LifetimeScopeLifestyle实例注册许多泛型类型实现的最佳技术。

The recommended method for this form of registration is something like this: 这种注册形式的推荐方法是这样的:

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

But this does not allow an instance of LifetimeScopeLifestyle to be passed in. 但是这不允许传入LifetimeScopeLifestyle的实例。

Below is what I came up with but I know it's not resilient enough as it is checking for any generic interface, not specifically IRepository<> . 下面是我提出的,但我知道它不够有弹性,因为它正在检查任何通用接口,而不是特定的IRepository<> Can anyone tell me how to do this? 谁能告诉我怎么做?

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: TLDR:

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

First of all, your query is wrong. 首先,您的查询是错误的。 It should have been: 应该是:

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

Second, the framework contains a GetTypesToRegister method to fetch these types for you, which excludes decorator types: 其次,框架包含一个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 };

But it gets better, the container contains an overload of the RegisterManyForOpenGeneric method that takes a callback delegate that allows you to do the registration as follows: 但它变得更好,容器包含RegisterManyForOpenGeneric方法的重载,该方法采用允许您按如下方式进行注册的回调委托:

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

But most importantly, the framework contains RegisterManyForOpenGeneric overloads that takes in an Lifetime . 但最重要的是,该框架包含接收Lifetime RegisterManyForOpenGeneric重载。 So you are able to simplify your registration to the following: 因此,您可以将注册简化为以下内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Castle Windsor中,如何为所有找到的通用类型的实现注册通用接口的许多实现之一? - In Castle Windsor, how to register ONE of many implementations of generic interface for ALL found implementations of generic type? 在SimpleInjector中用构造函数注册泛型类型如何? - Register generic types with constructor in SimpleInjector how? 在SimpleInjector版本3中注册通用类型 - Register generic types in SimpleInjector Version 3 Container.Register(Type,Assembly [])不注册通用实现 - Container.Register(Type, Assembly[]) does not register generic implementations 如何在autofac中注册Generic接口的所有实现? - How to register all implementations of Generic interface in autofac? SimpleInjector可以在运行时为泛型类型注册初始化程序吗? - Can SimpleInjector register an initializer for generic types at runtime? SimpleInjector如何为单个通用实现注册多个开放通用接口 - SimpleInjector HowTo Register multiple Open Generic Interfaces for a Single Generic Implementation 如何使用Ninject扫描泛型类型的所有实现 - How to scan for all implementations of a generic type with Ninject 如何注册泛型类型处理程序? - How to register generic type handler? Unity Container:如何通过命名空间注册和解析许多实现? - Unity Container: how to register and resolve many implementations by namespace?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM