gpt4 book ai didi

c# - 简单注入(inject)器 - RegisterCollection 和 RegisterDecorator 使用 Composite 模式和接口(interface)继承

转载 作者:太空宇宙 更新时间:2023-11-03 12:15:38 24 4
gpt4 key购买 nike

如何将类型注册为 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com