4

在回答这个问题时,我无法找出使用LifetimeScopeLifestyleSimpleInjector 中的实例注册许多泛型类型实现的最佳技术。

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

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

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

下面是我想出的,但我知道它没有足够的弹性,因为它正在检查任何通用接口,而不是专门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);
    }
}
4

1 回答 1

3

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方法接受一个回调委托,允许您按如下方式进行注册:

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

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

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    lifetimeScope, 
    typeof(IRepository<>).Assembly);
于 2013-04-18T17:38:58.817 回答