views:

95

answers:

1

I'm using the Agatha request/response library (and StructureMap, as utilized by Agatha 1.0.5.0) for a service layer that I'm prototyping, and one thing I've noticed is the large number of handlers that need to be created. It generally makes sense that any request/response type pair would need their own handler. However, as this scales to a large enterprise environment that's going to be A LOT of handlers.

What I've started doing is dividing up the enterprise domain into logical processor classes (dozens of processors instead of many hundreds or possibly eventually thousands handlers). The convention is that each request/response type (all of which inherit from a domain base request/response pair, which inherit from Agatha's) gets exactly one function in a processor somewhere.

The generic handler (which inherits from Agatha's RequestHandler) then uses reflection in the Handle method to find the method for the given TREQUEST/TRESPONSE and invoke it. If it can't find one or if it finds more than one, it returns a TRESPONSE containing an error message (messages are standardized in the domain's base response class).

The goal here is to allow developers across the enterprise to just concern themselves with writing their request/response types and processor functions in the domain and not have to spend additional overhead creating handler classes which would all do exactly the same thing (pass control to a processor function).

However, it seems that I still need to have defined a handler class (albeit empty, since the base handler takes care of everything) for each request/response type pair. Otherwise, the following exception is thrown when dispatching a request to the service:

StructureMap Exception Code: 202 No Default Instance defined for PluginFamily Agatha.ServiceLayer.IRequestHandler`1[[TSFG.Domain.DTO.Actions.HelloWorldRequest, TSFG.Domain.DTO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Agatha.ServiceLayer, Version=1.0.5.0, Culture=neutral, PublicKeyToken=6f21cf452a4ffa13

Is there a way that I'm not seeing to tell StructureMap and/or Agatha to always use the base handler class for all request/response type pairs? Or maybe to use Reflection.Emit to generate empty handlers in memory at application start just to satisfy the requirement?

I'm not 100% familiar with these libraries and am learning as I go along, but so far my attempts at both those possible approaches have been unsuccessful. Can anybody offer some advice on solving this, or perhaps offer another approach entirely?

+2  A: 

I'm not familiar with Agatha. But if you want all requests for IRequestHandler<T> to be fulfilled by BaseHandler<T>, you can use the following StructureMap registration:

For(typeof(IRequestHandler<>)).Use(typeof(BaseHandler<>));

When something asks for an IRequestHandler<Foo>, it should get a BaseHandler<Foo>.

Joshua Flanagan
It took a little bit of dirty work that I'll want to clean up, but you definitely pointed me in the right direction.My previous custom handler was being defined as:public class DomainRequestHandler<TREQUEST, TRESPONSE> : RequestHandler<TREQUEST, TRESPONSE> where TREQUEST : BaseRequest where TRESPONSE : BaseResponse, new()but now is:public class DomainRequestHandler<TREQUEST> : IRequestHandler<TREQUEST> where TREQUEST : BaseRequestThis involved implementing a few more procedures for the interface which don't actually do anything yet, so I'll see how that goes.Thanks!
David
Ug, sorry for the bad formatting there. I was hoping StackOverflow would keep the spacing :(
David