Question

I have an Entity Framework application connecting to an SQL server on a separate box. The program flow can be broken down in to two states:

  1. Init the composition root and register types using the Simple Injector DI framework
  2. Init application (does some reads and writes with the SQL database using Entity Framework)
  3. Based on a timer, a task function gets an instance for a command that is due to run ICommandHandler<CommandType> (command types vary)
  4. Calls Handle(commandType) on this instance to run the command
  5. Goes back to step 3

I need to protect the program from crashing in the event of loosing connection to the SQL server. Currently if the application looses SQL connection an unhandled exception will be thrown EntityException - The underlying provider failed on Open.

The program should be able to reset and resume operation once the server comes back online.

This question involves the use of the Simple Injector as it is the core of my application, I have some ideas on writing state transitions between an uninitialised and running state, but would like first to ask where the errors should be caught in a nice way using the features of Simple Injector - Specifically I am focusing on decorators but not sure if this is correct.

Open to any other recommend architecture, and how this might look from where errors are caught at a higher level allowing state changes to take place.

Code structure below

I am using Command/Handler approach:

public interface ICommandHandler<TCommand>
{
    void Handle(TCommand command);
}

On application bootup, all types implementing ICommandHandler<T> are registered:

public static void Bootstrap(Container container)
{
    container.RegisterManyForOpenGeneric(
        typeof(ICommandHandler<>),
        System.AppDomain.CurrentDomain.GetAssemblies());

    // bootstrap container
}

My command handler implementations are as so:

public class AddBusinessUnitCommand
{
    public string Name { get; set; }
    public float TimeZone { get; set; }
}

public class BusinessUnitCommandHandlers
    : ICommandHandler<AddBusinessUnitCommand>
{
    private IBusinessUnitService businessUnitService;

    public BusinessUnitCommandHandlers(
        IBusinessUnitService businessUnitService)
    {
        this.businessUnitService = businessUnitService;
    }

    public void Handle(AddBusinessUnitCommand command)
    {
        // do something
    }
}

I can then use the Simple Injector to get an instance of type, for example, ICommandHandler<AddBusinessUnitCommand> where an instantiated BusinessUnitCommandHandlers object will be returned allowing me to Handle() the command.

I have seen Simple Injector can use decorators which I can use to wrap Handle() procedure calls.

public class TransactionCommandHandlerDecorator<TCommand>
    : ICommandHandler<TCommand>
{
    private readonly ICommandHandler<TCommand> handlerToCall;
    private readonly IUnitOfWork unitOfWork;

    public TransactionCommandHandlerDecorator(
        IUnitOfWork unitOfWork, 
        ICommandHandler<TCommand> decorated)
    {
        this.handlerToCall = decorated;
        this.unitOfWork = unitOfWork;
    }

    public void Handle(TCommand command)
    {
         this.handlerToCall.Handle(command);
         unitOfWork.Save();
    }
}
Was it helpful?

Solution

I need to protect the program from crashing in the event of loosing connection to the SQL server.

... where the errors should be caught in a nice way using the features of Simple Injector - Specifically I am focusing on decorators but not sure if this is correct.

There are three important reasons to decorate ICommandHandler<T> implementations with generic decorators. First of all it prevents you from having any duplicate code in the application, since the decorator is written once, and wrapped around many ICommandHandler<T> implementations. Secondly, you can change the behavior of command handlers and add cross-cutting concerns without any changes to the consumers of these command handlers. Last, even when code reuse and consumer ignorance is not an issue, a decorator would still be useful if the behavior to add is logically part of the command handler. Validating the executed command for instance. This is something the consumer probably shouldn't care about, and is something you want to do during the call to Handle.

I expect that your 'command processor' (your timer) is a single piece of code and is part of your application's infrastructure (perhaps even part of the composition root). Since this is just a single piece of code, there is no reason to use a decorator to prevent code duplication and adding this crash protection as decorator would probably not win you that much either.

We could even argue that it might even be the responsibility of this piece of infrastructural code to do the crash protection (instead of being the responsibility of the command handler), especially since that piece of code must probably do things like command rescheduling (based on the failure type), or placing it in some sort of 'failed command queue' (to allow rerunning them manually). Perhaps your design could benefit from using the Circuit Breaker Pattern.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top