C# 责任链动态链
我正在开发一个应用程序,它使用责任链来处理请求。我知道如何构建链,但是如果你看下面的例子,我将不得不调用C# 责任链动态链,c#,design-patterns,chain-of-responsibility,C#,Design Patterns,Chain Of Responsibility,我正在开发一个应用程序,它使用责任链来处理请求。我知道如何构建链,但是如果你看下面的例子,我将不得不调用link1.Process(request)以启动链过程。我想弄明白的是,有没有一种方法可以把它当作一个集合,可以调用链的第一个链接,不管是什么?原因是,我知道基本元素是什么(最终的默认对象),但其他程序员可以将对象添加到链中,并可能将它们放置在链永远无法到达的位置 public class MergedFieldProcessor { public MergedFieldProce
link1.Process(request)代码>以启动链过程。我想弄明白的是,有没有一种方法可以把它当作一个集合,可以调用链的第一个链接,不管是什么?原因是,我知道基本元素是什么(最终的默认对象),但其他程序员可以将对象添加到链中,并可能将它们放置在链永远无法到达的位置
public class MergedFieldProcessor
{
public MergedFieldProcessor()
{
//Define CoR here
FieldProcessor link1 = new FieldProcessor();
FieldProcessor link2 = new FieldProcessor();
FieldProcessor link3 = new FieldProcessor();
link1.SetNextProcessor(link2);
link2.SetNextProcessor(link3);
}
}
public abstract class FieldProcessor
{
private FieldProcessor NextProcessor { get; set; }
public FieldProcessor()
{
this.NextProcessor = new SprocObject();
}
public void SetNext (FieldProcessor successor)
{
this.NextProcessor = successor;
}
//determines if this link in the change is responsible for the request
public abstract Boolean WillProcess(MergedFieldProcessorRequest request);
//performs the processing required for the tag
public abstract void ProcessField(MergedFieldProcessorRequest request);
//chain method that passes the request
public void ProcessRequest(MergedFieldProcessorRequest request)
{
if (!this.WillProcess(request))
this.NextProcessor.ProcessRequest(request);
else
this.ProcessField(request);
}
}
public class MergedFieldProcessorRequest
{
public MergedField Field { get; set; }
public Dictionary<string, string> SearchParams { get; set; }
}
如果他们没有修改启动流程的代码,比如说link4.process(request)
,那么link4将永远不会是链的一部分
简言之,是否可以动态构建链,以便如果有人将对象添加到集合中,它会自动添加到链中 您想让用户能够构建链吗。。。没有能力建立连锁店?
要么用户负责链接对象,要么扔掉链接,为FieldProcessor
s提供任何集合(然后按它们在集合中的顺序调用它们)
如果链接很重要,那么最好在处理之前对循环和无法访问的链接进行链验证。以下是我提出的解决方案。只需将每个处理器添加到集合中,然后迭代该集合以构建链,并处理链,只需调用this.Links[0]。处理(请求)代码>
#区域构建链集合;
this.Links=新列表()
{
新学员集合详细信息处理器(),
新的存储对象()
};
#末端区域;
#区域动态构建链
for(int i=0;i
您可以使用反射和一些递归
公共类MergedFieldProcessor
{
专用现场处理器优先;
专用FieldProcessor CreateLink(IEnumerator处理器)
{
if(processors.MoveNext())
{
FieldProcessor链接=(FieldProcessor)Activator.CreateInstance(processors.Current);
link.NextProcessor=CreateLink(处理器);
返回链接;
}
返回null;
}
公共合并字段处理器()
{
var processType=typeof(FieldProcessor);
var allProcess=processType.Assembly.GetTypes()
其中(t=>t!=processType&&processType.IsAssignableFrom(t));
first=CreateLink(allProcess.GetEnumerator());
}
公共无效句柄(MergedFieldProcessorRequest请求)
{
第一,处理请求(request);
}
}
这将确保所有可能的链接都被创建并链接在一起,但有一个警告:最后一个链接将有一个null
后续链接,通常它必须是一个更紧密的链接(将处理任何请求)
并将其用作
class Program
{
static void Main(string[] args)
{
DefaultClass dc = new DefaultClass();
FirstClass fc = new FirstClass();
dc.SetSuccessor(fc);
SecondClass sc = new SecondClass();
dc.SetSuccessor(sc);
ThirdClass tc = new ThirdClass();
dc.SetSuccessor(tc);
dc.Execute();
}}
您可以动态添加或删除对象您对此考虑得太多了。如果你的消费者遗漏了一个链接,那么很可能是故意的。如果他们没有,那是他们的错。这类似于强制编译器确保while循环是闭合的,因为可以使用while循环生成无限循环。所有这些看起来都没有使用C#和.Net提供的任何良好功能。这背后的真正要求是什么?我相信有更好的方法来实现你的需求,比如MEF。
#region Build Chain Collection;
this.Links = new List<FieldProcessor>()
{
new StudentEnrollmentDetailsProcessor(),
new SprocObject()
};
#endregion;
#region Build Chain Dynamically
for (int i = 0; i < this.Links.Count(); i++)
{
if (i < this.Links.Count())
{
this.Links[i].SetNext(this.Links[i + 1]);
}
}
#endregion;
public class MergedFieldProcessor
{
private FieldProcessor first;
private FieldProcessor CreateLink(IEnumerator<Type> processors)
{
if(processors.MoveNext())
{
FieldProcessor link = (FieldProcessor)Activator.CreateInstance(processors.Current);
link.NextProcessor = CreateLink(processors);
return link;
}
return null;
}
public MergedFieldProcessor()
{
var processType = typeof(FieldProcessor);
var allProcess = processType.Assembly.GetTypes()
.Where(t => t != processType && processType.IsAssignableFrom(t));
first = CreateLink(allProcess.GetEnumerator());
}
public void Handle(MergedFieldProcessorRequest request)
{
first.ProcessRequest(request);
}
}
public abstract class AbCommon
{
public virtual AbCommon Successor { get; protected set; }
public virtual void Execute()
{
if (Successor != null)
{
Successor.Execute();
}
}
public virtual void SetSuccessor(AbCommon successor)
{
if (Successor != null)
{
Successor.SetSuccessor(successor);
}
else
{
this.Successor = successor;
}
}
}
class DefaultClass : AbCommon
{
public override void Execute()
{
Console.WriteLine("DC");
base.Execute();
}
}
class FirstClass: AbCommon
{
public override void Execute()
{
Console.WriteLine("FC");
base.Execute();
}
}
class SecondClass: AbCommon
{
public override void Execute()
{
Console.WriteLine("SC");
base.Execute();
}
}
class ThirdClass: AbCommon
{
public override void Execute()
{
Console.WriteLine("TC");
base.Execute();
}
}
class Program
{
static void Main(string[] args)
{
DefaultClass dc = new DefaultClass();
FirstClass fc = new FirstClass();
dc.SetSuccessor(fc);
SecondClass sc = new SecondClass();
dc.SetSuccessor(sc);
ThirdClass tc = new ThirdClass();
dc.SetSuccessor(tc);
dc.Execute();
}}