Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将装饰器和故障切换模式与Autofac/other容器混合使用时的正确方法_C#_.net_Containers_Decorator_Failover - Fatal编程技术网

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