我正在阅读事件驱动设计。我在实践中无法理解其中的一些问题。我正在考虑将此用于监视,解析和处理来自第三方TCP流的信息的Windows服务。以下是一个体面的方法,还是我错过了什么?
我的计划是让主要服务只是事件的容器:
public class MyService
{
public void RegisterAgent(ServiceAgent agent)
{
Log("Initializing agent " + agent);
agent.Initialize(this);
Log("Done intializing agent " + agent);
}
public void Log(string messageText)
{
OnSimpleLogEventLogged(this, new SimpleLogEventArgs(messageText));
}
protected void Raise<T>(EventHandler<T> eventHandler, object sender, T args) where T : EventArgs
{
var handler = eventHandler;
if (handler == null) return;
handler(sender, args);
}
public event EventHandler<SimpleLogEventArgs> SimpleLogEventLogged;
protected void OnSimpleLogEventLogged(object sender, SimpleLogEventArgs args)
{
Raise(SimpleLogEventLogged, sender, args);
}
public event EventHandler<TextRecievedEventArgs > TextRecieved;
public void OnTextRecieved(object sender, TextRecievedEventArgs args)
{
Raise(TextRecieved, sender, args);
}
public event EventHandler<TextParsedEventArgs> TextParsed;
public void OnTextParsed(object sender, TextParsedEventArgs args)
{
Raise(TextParsed, sender, args);
}
...
}
然后,使用MEF或类似方法,我将注册“ServiceAgent”实例,它只是处理和/或引发事件,可选地在后台线程上执行。例如:
public class TextParsingAgent : ServiceAgent
{
public override void Initialize(MyService service)
{
service.TextRecieved += TextRecieved;
base.Initialize(service);
}
void TextRecieved(object sender, TextRecievedEventArgs e)
{
ThreadPool.QueueUserWorkItem(TextRecievedAsync, e);
}
private void TextRecieved(object state)
{
var e = (TextRecievedEventArgs)state;
//TODO:Parse text into something meaningful and store in textParseEventArgs
service.OnTextParsed(textParseEventArgs);
}
}
答案 0 :(得分:1)
我个人认为它对您的代码来说是一个相当不错的整体结构,它可以轻松地将逻辑单元分离到自己的操作中,如果您需要设置不同的服务代理,通过通知服务它可以在将来实现良好的可扩展性后面。
答案 1 :(得分:1)
如果Raise()
方法仅用于简化空检查,则可能需要使用lambda表达式将事件处理程序初始化为非null,如下所示:
public event EventHandler<TextParsedEventArgs> TextParsed = (sender, e) => { };
然后你可以在没有空检查的情况下调用TextParsed(...)
,这可能会使代码更容易理解。