Luc
Luc

Reputation: 1850

How to offer (optional) notification handlers in MediatR

I am using Jimmy Bogard's MediatR library in a console app to call various SOAP end points. The app is configured and working beautifully through the magic of a few IRequestHandler<T1, T2> implementations.

However, in all of my command line utility calls, there are 2 flags that allow the user to save the Xml response (along with other details) to a database table and / or save a text file. I feel like this is a great opportunity for an INotificationHandler<T>, but I can't seem to wrap my head around the workflow.

It is my understanding that once registered via IoC, they are always listening. However, (in my case) they would be dynamically set depending on the command line flags.

public class SoapRequest : IRequest<string>
{
   // lots of properties here...

   public bool SkipDatabase { get; set; }
   public string OutputFile { get; set; }
}

// in my handler
public class SoapRequestHandler : IRequestHandler<SoapRequest, string>
{

   public async Task<string> Handler(SoapRequest request, CancellationToken token)
   {
      // fetches soap data, and does other stuff here... 
      var responseXml = await _endPoint.DoStuff(request.Prop1, ...);

      if (!request.SkipDatabase)
      {
         var dbCommand = new DatabaseCommand 
         { 
            ResponseString = responseXml, 
            ... 
         };

         await _mediator.Send(dbCommand, token);
      }

      if (!string.IsNullOrEmpty(request.OutputFile))
      {
         var fileCommand = new XmlFileCommand 
         { 
            FileName = request.OutputFile, 
            Xml = responseXml, 
            ... 
         };

         await _mediator.Send(fileCommand, token);
      }

      return responseXml;
   }
}

Consider The Following:

This will save to the results to a database table

> myapp fetch_users 

This will write the results to a text file, and NOT save to the database

> myapp fetch_users --output-file="c:\temp\users.xml" --skip-db

I'm currently managing this with 2 separate IRequest commands / handlers, and it's starting to exude a code smell. Some of my low-level handlers are exposing higher-level properties on the request objects that don't apply. I'd like to make use of notification handlers to solve this, but only register it on demand, depending on the users CLI flags.

Since MediatR is configured in IoC at start up, this presents a problem for me. My concern is that if I register two notification handlers (DatabaseNotificationHandler and FileSystemNotificationHandler), they will always be listening, and I can't figure out how to get the flags into the handlers dynamically without passing them to my deepest handlers. Is there a better way?

#WWJBD - What would Jimmy Bogard do? :)

Upvotes: 1

Views: 1797

Answers (1)

Luc
Luc

Reputation: 1850

This issue was solved in jbogard/MediatR Github Issues.

The solution was to NOT nest multiple MediatR.Send(...) calls or even use MediatR.Publish(...), but instead refactor my code to proper business logic in my main handler. My soap requests have the required properties on them that get converted to domain types, which I then use to determine how things work on each soap call (ie. database capture and Xml file serialization).

Thank you to @lilasquared for the tip.

Upvotes: 1

Related Questions