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