如何将类型注册为 IPollingService<TContext>
这样它们就可以通过 container.RegisterDecorator(typeof(IPollingService<>), typeof(ContextAwarePollingServiceDecorator<>))
进行装饰, 但也将它们注册为 IPollingService
的集合这样它们就会被注入(inject)到 CompositePollingService
的构造函数中通过container.RegisterCollection(typeof(IPollingService), types)
?
我有以下接口(interface):
public interface IPollingService { Task Poll(); }
public interface IPollingService<TContext> : IPollingService
where TContext : CustomContext { TContext Context { get; } }
和 IPollingService 的复合模式实现:
class CompositePollingService : IPollingService
{
private readonly IEnumerable<IPollingService> _pollingServices;
public CompositePollingService(IEnumerable<IPollingService> pollingServices) =>
_pollingServices = pollingServices;
public async Task Poll() =>
await Task.WhenAll(_pollingServices.Select(s => s.Poll()));
}
我对 IPollingService
的所有其他实现实际执行IPollingService<TContext>
但我将它们传递到 CompositePollingService
构造函数为 IEnumerable<IPollingService>
因为会有 IPollingService<TContext>
的混合, 和 CompositeService
只需要知道 IPollingService.Poll()
.
我根据配置有条件地将类型添加到列表中,并使用该列表为 CompositePollingService
的构造函数注册集合:
List<Type> types = new List<Type>();
if (// config says to use TEST Context)
types.Add(typeof(PollingService<TestContext>)); // impl. of IPollingService<TContext>
if (// config says to use LIVE Context)
types.Add(typeof(PollingService<LiveContext>)); // impl. of IPollingService<TContext>
container.RegisterCollection(typeof(IPollingService), types);
我有一个 IPollingService<TContext>
的装饰器:
class ContextAwarePollingServiceDecorator<TContext>
: IPollingService<TContext> where TContext: CustomContext
{
private readonly IPollingService<TContext> _decoratee;
public ContextAwarePollingServiceDecorator(IPollingService<TContext> decoratee)
=> _decoratee = decoratee;
public async Task Poll() {
// decoration here...
await _decoratee.Poll(cancellationToken);
}
public TContext Context => _decoratee.Context;
}
但是,我的装饰器没有应用到我的 IPollingService<TContext>
实现,当我这样注册时:
container.RegisterDecorator(typeof(IPollingService<>),
typeof(ContextAwarePollingServiceDecorator<>));
如何将类型注册为 IPollingService<TContext>
但也将它们注册为 IPollingService
的集合这样它们就会被注入(inject)我的CompositePollingService
实现?
最佳答案
您可以使用以下代码执行此操作:
var ls = Lifestyle.Transient;
// Create a collection of InstanceProducer instances for IPollingService<T> registrations
var producers = new InstanceProducer[]
{
ls.CreateProducer<IPollingService<TestContext>, PollingService<TestContext>>(container),
ls.CreateProducer<IPollingService<LiveContext>, PollingService<LiveContext>>(container),
};
// Register a decorator that wraps around all IPollingService<T> instances
container.RegisterDecorator(typeof(IPollingService<>),
typeof(ContextAwarePollingServiceDecorator<>));
// Register the IEnumerable<IPollingService> that contains all IPollingService<T> instances
container.RegisterInstance(producers.Select(p => (IPollingService)p.GetInstance()));
// Register the composite
container.Register<IPollingService, CompositePollingService>(Lifestyle.Singleton);
关于c# - 简单注入(inject)器 - RegisterCollection 和 RegisterDecorator 使用 Composite 模式和接口(interface)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49903476/