Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Architectural help for specifying which handler to use #49

Closed
alexjamesbrown opened this issue Aug 10, 2015 · 2 comments
Closed

Architectural help for specifying which handler to use #49

alexjamesbrown opened this issue Aug 10, 2015 · 2 comments

Comments

@alexjamesbrown
Copy link

I'm working on a system where I've started using Mediatr to separate out our commands / queries.

One such request is GetAccountInformation

I've simplified the logic down, but the kind of issue I'm having, is we need to query a service to find out which sub-system to use, in order to get the account information.

Probably better to illustrate with code...

So, currently, in a 'core' namespace/assembly, I have

public class GetAccountInformationRequest : IAsyncRequest<AccountInformation>
{
    public string AccountReference {get; set}
}

Then, the handler looks something like this

public class GetAccountInformationRequestHandler :       
    IAsyncRequestHandler<GetAccountInformationRequest , AccountInformation>
{
    private readonly IMediator _mediator;

    public GetAccountInformationRequestHandler(IMediator mediator)
    {
        _mediator = mediator;
    }

    public async Task<AccountInformation> Handle(GetAccountInformationRequest request)
    {
        //this sends a different request off to another handler which determines which sub system to use
        var subSystem = await _mediator.SendAsync(new GetAccountSubSystemRequest(request.AccountReference));

        //this is rubbish, but I've only done this to illustrate the kind of thing I need to do
        if(subSystem == 'SystemA')
            return await _mediator.SendAsync(new SystemA.GetAccountInformationRequestFromSystemRequest(request.AccountReference));
        if(subSystem == 'SystemB')
            return await _mediator.SendAsync(new SystemB.GetAccountInformationRequestFromSystemRequest(request.AccountReference));
        if(subSystem == 'SystemC')
            return await _mediator.SendAsync(new SystemC.GetAccountInformationRequestFromSystemRequest(request.AccountReference));

        throw new Exception("Unknown sub system");
    }
}

As you can see, I've then got additional namespaces (in separate assemblies) with the specific requests in -
This does feel a bit rubbish. For a start, it feels like there's a lot of duplication here - really, I just need the specific handlers
And the obvious violation of Open/Closed

Any ideas?

@alexjamesbrown
Copy link
Author

Feels almost like I need to be able to do something like

_mediator.SendAsync(request, "SystemA");

... and being able to 'tag' the implementations of the handler (based on namespace or something) during my container setup

unless of course, there's a better, more concrete and less string based way!

@josephwoodward
Copy link
Contributor

From my understanding it looks like you should take a look at the abstract factory pattern (though I'm keen to see other's approaches to the problem are).

This would turn your request into something a little more like this:

public async Task<AccountInformation> Handle(GetAccountInformationRequest request, ISubSystemAbstractFactory abstractFactory)
{
    var subSystem = abstractFactory.CreateSubSystem(request.AccountReference);

    return await _mediator.SendAsync(subSystem.GetAccountInformationRequestFromSystemRequest(request.AccountReference);
}

This post should give you a better understanding of the pattern - http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/

@jbogard jbogard closed this as completed Dec 30, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants