[英]Design pattern for handling multiple message types with callback or event raising
I read about Strategy pattern in this question. 我在这个问题中读到了战略模式。 I ran into a problem when wrapping all this in MessageProcessor, and cannot give the user of my class any strong typed callback.
将所有这些都包装在MessageProcessor中时遇到了一个问题,并且无法为我的类用户提供任何强类型的回调。
public class MessageProcessor
{
private IMessageProcessing Processing {get; set;} // a processing strategy
public void ProcessMessage(HubMessage message) //SignalR data message
{
ContentBase content = MessageProcessingBase.GetMessageContent(message); //just get content object from message
if (content is DocumentFile) //this content holds info about file to download
Processing = new DocumentFileProcessing();//implementation of IMessageProcessing strategy interface
Processing.ProcessMessage(message); //here a file is being downloaded and I want to raise event or call a callback method to inform a client (this class's caller) about a path of downloaded file
}
}
I tried to explain my problem in code comments. 我试图在代码注释中解释我的问题。 Is it possible to give a user of my DLL any typed callback if I only provide a MessageProcessor class that determines a type of message and calls typed strategy class?
如果仅提供确定消息类型并调用类型化策略类的MessageProcessor类,是否可以为DLL用户提供任何类型化的回调? Or I should leave the user to write strategy determination code (in this case MessageProcessor)?
还是我应该让用户编写策略确定代码(在这种情况下为MessageProcessor)?
I know I can have event to call when processing is done, but that event would be in base MessageProcessing class, so it cannot have typed event arguments. 我知道处理完成后可以调用事件,但是该事件将在基本MessageProcessing类中进行,因此它不能具有类型化的事件参数。 EDIT I provided some more code, to help understand what I need.
编辑我提供了更多代码,以帮助了解我所需要的。
//lib code
public class Message
{
public string From { get; set; }
public string To { get; set; }
public MessageContentBase Conent{get;set;}
}
public class MessageContentBase
{
public string Note{get; set;}
}
public class DocumentFile: MessageContentBase
{
public string FilePath { get; set; }
}
public abstract class MessageProcessing
{
public abstract void ProcessMessage(Message message);
}
public class DocumentFileMessageProcessing:MessageProcessing
{
public override void ProcessMessage(Message message)
{
DocumentFile df = message.Conent as DocumentFile;
//1. download file
//2. raise event or do callback in client code with parameter df.FilePath
}
}
public class SomeOtherProcessing : MessageProcessing
{
public override void ProcessMessage(Message message)
{
MessageContentBase content = message.Conent;
//log.WriteLine("Message was from " + message.From);
}
}
public class MessageProcessor
{
MessageProcessing processing;
public void ProcessMessage(Message message)
{
if (message.Conent is DocumentFile)
processing = new DocumentFileMessageProcessing();
//else if, else if.....
processing.ProcessMessage(message);
}
}
// end lib code
public class Program //client code
{
public static void Main(string[] args)
{
Message m = new Message();
MessageProcessor mp = new MessageProcessor();
mp.ProcessMessage(m);
// need something to call return-result-type-dependent post processing code
}
}
It is not strictly necessary to use an interface for the strategy pattern. 并非必须将接口用于策略模式。 You can declare an abstract class MessageProcessing and a method ProcessMessage which uses the template pattern.
您可以声明一个抽象类MessageProcessing和一个使用模板模式的ProcessMessage方法。 In his logic, the code executes internal processing method and then raises an event.
按照他的逻辑,代码执行内部处理方法,然后引发一个事件。
Something like this: 像这样:
internal abstract class MessageProcessing {
// TODO: declare event variable
abstract string ProcessInternalMessage(HubMessage message);
void ProcessMessage(HubMessage message) {
// Here he call the ProcessInternalMessage which returns
// the path. Depending on the derived class the logic or the processor.
string path = this.ProcessInternalMessage(message);
// here we raise event with the path in the parameters
}
}
As you can see, the ProcessMessage acts as a template. 如您所见,ProcessMessage充当模板。 This means that it has a logic flow (very simple, just two lines of code) in which first executes an abstract method.
这意味着它具有逻辑流程(非常简单,只有两行代码),其中首先执行抽象方法。 After that, it raise the event.
之后,它引发事件。
The abstract method must be implemented for each class that derives from this class. 必须为从该类派生的每个类实现抽象方法。 This method has the logic of your classes that implement your current interface.
此方法具有实现当前接口的类的逻辑。
With this, you only execute methods on the abstraction, and internally the event is raised. 这样,您仅在抽象上执行方法,并且在内部引发事件。
Is that what you need? 那是你需要的吗?
Greetings! 问候!
I ran into a problem when wrapping all this in MessageProcessor, and cannot give the user of my class any strong typed callback.
将所有这些都包装在MessageProcessor中时遇到了一个问题,并且无法为我的类用户提供任何强类型的回调。
The problem here is that MessageProcessor
creates all MessageProcessing
instances. 这里的问题是
MessageProcessor
创建所有MessageProcessing
实例。
Or I should leave the user to write strategy determination code (in this case MessageProcessor)?
还是我应该让用户编写策略确定代码(在这种情况下为MessageProcessor)?
The solution is to write a MessageProcessor
, that can be configured by the user by registering MessageProcessing
instances. 解决方案是编写一个
MessageProcessor
,用户可以通过注册MessageProcessing
实例进行配置。
Is it possible to give a user of my DLL any typed callback if I only provide a MessageProcessor class that determines a type of message and calls typed strategy class?
如果仅提供确定消息类型并调用类型化策略类的MessageProcessor类,是否可以为DLL用户提供任何类型化的回调?
Configuration phase: 配置阶段:
MessageProcessor
instance provided by the library MessageProcessor
实例 MessageProcessings
, provided by the library or by the user, registers callbacks and subscribes to MessageProcessings
events MessageProcessings
,注册回调并订阅MessageProcessings
事件 MessageProcessings
in the MessageProcessor
MessageProcessings
中注册所有创建的MessageProcessor
Message processing phase: 消息处理阶段:
MessageProcessor
to process a Message
MessageProcessor
来处理Message
MessageProcessor
looks though registered MessageProcessings
for a MessageProcessing
, capable of processing the Message
MessageProcessor
通过已注册的MessageProcessings
查找一个能够处理Message
的MessageProcessing
MessageProcessor
passes the Message
to the found MessageProcessing
MessageProcessor
传递Message
到所找到的MessageProcessing
MessageProcessing
makes all necessary callbacks and raises events to interact with the user MessageProcessing
进行所有必要的回调并引发事件以与用户交互 Hint: 暗示:
To check if MessageProcessing
is capable of processing a Message
add abstract bool CanProcess(Message)
method to the base MessageProcessing
class and override it in concrete MessageProcessing
classes. 若要检查
MessageProcessing
是否能够处理Message
,请在基本MessageProcessing
类中添加抽象bool CanProcess(Message)
方法,并在具体的MessageProcessing
类中重写它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.