[英]Conditionally register collection in Simple Injector
我想根据消费者是谁有条件地将类型注册到集合中。 就像是:
Container.Collection.RegisterConditionally(
typeof(IEventHandler<>),
myPublisherTypes,
c => c.Consumer.ImplementationType == typeof(PublishEventDecorator<,>));
Container.Collection.RegisterConditionally(
typeof(IEventHandler<>),
myTypes,
c => c.Consumer.ImplementationType != typeof(PublishEventDecorator<,>));
场景是我希望将某些类型的IEventHandler<>
作为集合在PublishEventDecorator
的构造函数中解析; IEnumerable<IEventHandler<TEvent>>
。 并且 rest 在其他任何地方被请求解决。
这可能吗?
尽管 Simple Injector 包含几个允许您有条件地注册 collections 的功能,但它缺少任何开箱即用的功能,允许您在 collections 的开放通用抽象上执行此操作。
但是有办法解决这个问题。 例如,您可以将InstanceProducer
实例列表注入装饰器。 这将导致如下所示的注册:
Container.Register(typeof(IPublishEvent<>), typeof(PublishEvent<>));
Container.RegisterDecorator(typeof(IPublishEvent<>), typeof(PublishEventDecorator<>));
Container.Collection.Register(typeof(IEventHandler<>), myTypes);
// Create a list of InstanceProducer instances for the list of publisher types.
// InstanceProducers are Simple Injector's registration factories. They are used
// to resolve instances from the container.
InstanceProducer[] myPublisherTypesProducers = (
from implementation in myPublisherTypes
from service in implementation.GetClosedTypesOf(typeof(IEventHandler<>))
select Lifestyle.Transient.CreateProducer(service, implementation, Container))
.ToArray();
// This conditional registration injects the instance producers into the decorator.
Container.RegisterConditional<InstanceProducer[]>(
Lifestyle.Singleton.CreateRegistration(
typeof(InstanceProducer[]), myPublisherTypesProducers, Container),
c => c.Consumer.ImplementationType
.GetClosedTypesOf(typeof(PublishEventDecorator<>)).Any());
此注册的结果是您需要专门制作装饰器,因为它需要依赖于InstanceProducer
实例列表。 有了它,它开始依赖于 Simple Injector。 因此,将装饰器移动到您的Composition Root中是一种很好的做法。 这是它可能的实现:
public class PublishEventDecorator<T> : IPublishEvent<T>
{
private readonly IPublishEvent<T> decoratee;
private readonly InstanceProducer[] handlerProducers;
public PublishEventDecorator(
IPublishEvent<T> decoratee, InstanceProducer[] handlerProducers)
{
this.decoratee = decoratee;
this.handlerProducers = handlerProducers;
}
private IEnumerable<IEventHandler<T>> Handlers =>
from producer in this.handlerProducers
where producer.ServiceType == typeof(IEventHandler<T>)
select (IEventHandler<T>)producer.GetInstance();
public void Publish(T @event)
{
// Do something with handlers
foreach (var handler in this.Handlers) { }
// Invoke decoratee.
this.decoratee.Publish(@event);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.