C# 使用条件注册开放泛型

C# 使用条件注册开放泛型,c#,inversion-of-control,simple-injector,fluentvalidation,C#,Inversion Of Control,Simple Injector,Fluentvalidation,是否可以在不指定实现类型的情况下使用寄存器条件(类似于寄存器的工作方式,但使用条件) 我正在使用Simple Injector为我的CQRS/MVC应用程序连接fluent验证。到目前为止,注册验证器(MVC和CQRS堆栈装饰器管道都使用)非常简单: container.Register(typeof(IValidator<>), assemblies, lifestyle); container.RegisterConditional( typeof(IValidator

是否可以在不指定实现类型的情况下使用
寄存器条件
(类似于
寄存器
的工作方式,但使用条件)

我正在使用Simple Injector为我的CQRS/MVC应用程序连接fluent验证。到目前为止,注册验证器(MVC和CQRS堆栈装饰器管道都使用)非常简单:

container.Register(typeof(IValidator<>), assemblies, lifestyle);

container.RegisterConditional(
    typeof(IValidator<>), 
    typeof(ValidateNothingDecorator<>), 
    Lifestyle.Singleton, 
    c => !c.Handled)
我的备用位置是查找实现
ivalidater
但不实现
IProvideWarnings
的所有类型,并将其传递到
Register
,但是,我宁愿在注册调用中使用谓词,而不是使用不同的查找


谢谢

我解决这个问题的方法是使用我的后备位置

请记住,下面的代码中有一个非标准方法(但应该足够直截了当),它看起来像:

 var validatorTypes = assemblies.SelectMany(a => a.GetTypes().Where(t =>
            t.IsClass && !t.IsAbstract && t.IsPublic &&
            t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IValidator<>)) &&
            !t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IProvideWarnings<>))
        )).ToList();

IocContainer.Register(typeof(IValidator<>), validatorTypes, IocContainer.DefaultLifestyle);

IocContainer.RegisterConditional(typeof(IValidator<>), typeof(ValidateNothingDecorator<>), Lifestyle.Singleton, c => !c.Handled && !c.ServiceType.DoesImplement(typeof(IProvideWarnings)));
var validatorTypes=assemblies.SelectMany(a=>a.GetTypes()。其中(t=>
t、 IsClass&&!t.IsaStract&&t.IsPublic&&
t、 GetInterfaces().Any(i=>i.IsGenericType&&i.GetGenericTypeDefinition()==typeof(IValidator))&&
!t.GetInterfaces().Any(i=>i.IsGenericType&&i.GetGenericTypeDefinition()==typeof(IProviderWarnings))
)).ToList();
IocContainer.Register(typeof(IValidator)、validatorTypes、IocContainer.DefaultLifestyle);
IocContainer.RegisterCondition(类型of(IValidator)、类型of(ValidateNothingDecorator)、生活方式.Singleton,c=>!c.Handled&!c.ServiceType.DoesImplement(类型of(IProviderWarnings));

正如您已经注意到的,Simple Injector包含一个超负荷的
寄存器
,允许提供要注册的类型列表。虽然您可以自己对程序集进行反思,但Simple Injector包含一个方便的
GetTypeStoreRegister
方法,可以为您实现这一点。此
getTypeStoreRegister
将自动为您过滤装饰器和泛型类型定义

以下注册将实现此功能:

var validatorTypes =
    container.GetTypesToRegister(typeof(IValidator<>))
        .Where(typeof(IProvideWarnings).IsAssignableFrom);

container.Register(typeof(IValidator<>), validatorTypes, lifestyle);
var验证程序类型=
container.getTypeStoreRegister(typeof(IValidator))
.Where(类型为(i提供警告)。可从中识别);
容器注册(类型(IValidator)、验证类型、生活方式);

谢谢,这比我的代码要简洁得多,而且我不知道(或者至少没有深入阅读,没有意识到)使用
GetTypeStoreRegister
。我会用这个!您的ValidateNothingDecorator实际上不是一个Decorator,而是一个空对象。
var validatorTypes =
    container.GetTypesToRegister(typeof(IValidator<>))
        .Where(typeof(IProvideWarnings).IsAssignableFrom);

container.Register(typeof(IValidator<>), validatorTypes, lifestyle);