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:
- Init the composition root and register types using the Simple Injector DI framework
- Init application (does some reads and writes with the SQL database using Entity Framework)
- Based on a timer, a task function gets an instance for a command that is due to run
ICommandHandler<CommandType>(command types vary) - Calls
Handle(commandType)on this instance to run the command - 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();
}
}