我正在尝试构建一个消息可能是请求的小消息/事件系统。
请求处理程序实现IHandlerOf<T>
接口,如
public class UserService : IHandlerOf<ISearchRequest>
{
private void ProccessRequest(ISearchRequest request)
{
}
}
我不确定我应该如何处理回复,因为多个处理程序可以“回答”请求。你会如何设计回复部分?在消息代理中构建一个回复列表,或者在进程方法中包含回复对象,让所有处理程序对同一个回复对象起作用?
示例将不胜感激。
或者您有现有解决方案的链接吗?使用服务总线(如nservicebus)似乎有点矫枉过正,因为一切都在进行中。
我目前的解决方案(正在进行的工作)。代理通过检查为IHandlerOf<>
中使用的请求类型注册的BeginRequest
接口来创建响应对象。
解决方案的缺点是没有任何关系请求和回复,如果不正确的回复类型映射到请求类型,将不会产生编译错误。虽然如果请求有两种不同的响应类型,代理会在注册过程中抛出错误。
代理在每个处理程序调用周围使用try / catch,以便能够继续处理请求处理程序,即使其中一个引发异常。我还没有真正决定如何处理异常。一个处理程序可能会抛出,而另一个处理程序成功处理了请求。
处理程序界面:
// interface defining a class which would handle a request
public interface IHandlerOf<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
void ProcessRequest(IRequestContext<TRequest, TResponse> context);
}
示例实现
public class FindContactsRequest : IRequest
{
public string SearchValue { get; set; }
}
public class FindContactsResponse : IResponse
{
public ICollection<string> Contacts { get; set; }
}
public class UserService : IHandlerOf<FindContactsRequest, FindContactsResponse>
{
public void ProcessRequest(IRequestContext<FindContactsRequest, FindContactsResponse> context)
{
if (context.Request.SearchValue == "blabla")
{
context.Response.Contacts.Add("My contact name");
}
}
}
经纪人界面
public interface IMessageBroker
{
IAsyncResult BeginRequest(IRequest request, AsyncCallback callback, object state);
IResponse EndRequest<T>(IAsyncResult result) where T : IResponse;
}
样本用法
var ar = _broker.BeginRequest(new FindContactsRequest("blabla"));
var response = _broker.EndRequest<FindContactsResponse>(ar);
Console.WriteLine("Woho, found " + response.Contacts.Count + " contacts.");
答案 0 :(得分:1)
如果所有处理程序都针对同一个回复对象,那么回复对象需要某种逻辑来防止坏处理程序破坏其他处理程序的回复。也就是说,如果回复对象包含List<string>
,例如,行为不当的处理程序可能会在列表上调用Clear
并且所有这些都将丢失。因此,回复对象需要包装该列表(通过提供AddReply
方法或其他方法)来防止此类行为。
此外,如果所有处理程序都针对同一个回复对象,则多线程请求处理变得更加困难。 reply对象必须处理线程同步以防止数据损坏。
另一方面,如果消息代理处理组合回复,则会更加灵活。它可以依次调用每个处理程序(顺序),也可以使用异步调用并行运行多个处理程序。看起来消息代理将更容易,更灵活地放置组合回复的逻辑。