C# 将装饰器和故障切换模式与Autofac/other容器混合使用时的正确方法
我的课程结构如下:C# 将装饰器和故障切换模式与Autofac/other容器混合使用时的正确方法,c#,.net,containers,decorator,failover,C#,.net,Containers,Decorator,Failover,我的课程结构如下: ConcreteCommandSender(实例1)尝试通过非托管资源发送内容,然后Failproof CommandSender在可能出现错误时尝试通过BackupPool将命令传递给其他命令发送者BackupPool知道所有可用的命令发送器,并选择不同于原始发送器的(备份的)命令,然后执行所选的ICommandSender(实例2),该命令被实现为ConcreteCommandSender(实例2)。另见下图 问题是,我不知道如何向装饰程序正确注册类型以使其正常工作。到目
ConcreteCommandSender(实例1)
尝试通过非托管资源发送内容,然后Failproof CommandSender
在可能出现错误时尝试通过BackupPool
将命令传递给其他命令发送者BackupPool
知道所有可用的命令发送器,并选择不同于原始发送器的(备份的)命令,然后执行所选的ICommandSender(实例2)
,该命令被实现为ConcreteCommandSender(实例2)
。另见下图
问题是,我不知道如何向装饰程序正确注册类型以使其正常工作。到目前为止,我遇到了一个问题,Autofac在BackupPool
中创建了新的ICommandSender
实例,而不是使用在容器配置中创建的实例(因此使用现有实例)。在BackupPool
的构造函数中有一个IEnumerable
,但我也手动解析了第一个ICommandSender
同样奇怪的是,BackupPool
注册为单个实例时,每次都会为decorator创建一个新的实例,并且我有循环依赖关系,因为Autofac不想使用我的BackupPool
的单个实例-BackupPool
有所有命令发送者的列表,如上所述
问题是-如何正确管理所有命令发送者的列表,将其与那些装饰器混合在一起
**主要目标是:
interface ICommandSender
{
void Send(ICommand command);
}
class FailProofCommandSender : ICommandSender
{
FailProofCommandSender(BackupPool backupPool) { }
void Send(ICommand command)
{
// try to send command and catch in OnError
}
private OnError(ICommand command)
{
ICommandSender sender = backupPool.GetAnyExcept(this); // there is same context on ICommandSender per decorators family, so same sender is checked against this context
sender.Send(command);
}
}
类备份工具
{
i收集发送器;
//每次都会为每个Failproof CommandSender创建BackupPool,但为什么?它注册为single:(
BackupPool(函数工厂)
{
foreach(0,…,n)=>senders.Add(factory());
}
ICommandSender GetAnyExcept(ICommandSender)
{
返回此文件。发件人
.Where(…)//Where发件人不是来自同一上下文
.Random();
}
}
builder.RegisterType().As();
builder.RegisterDecorator();
builder.RegisterType()
.AsSelf()
.SingleInstance();
图表:
class BackupPool
{
ICollection<ICommandSender> senders;
// BackupPool is created each time for every FailProofCommandSender, but why? It's registered as single :(
BackupPool(Func<ICommandSender> factory)
{
foreach(0, ..., n) => senders.Add(factory());
}
ICommandSender GetAnyExcept(ICommandSender sender)
{
return this.senders
.Where(...) // where sender is not from same context
.Random();
}
}
builder.RegisterType<ConcreteCommandSender>().As<ICommandSender>();
builder.RegisterDecorator<FailProofCommandSender, ICommandSender>();
builder.RegisterType<BackupPool>()
.AsSelf()
.SingleInstance();