我有一个实体框架应用程序连接到一个单独的盒子上的 SQL 服务器。程序流程可以分为两种状态:
- 使用 Simple Injector DI 框架初始化组合根和注册类型
- 初始化应用程序(使用实体框架对 SQL 数据库进行一些读写操作)
- 基于计时器,任务函数获取即将运行的命令的实例
ICommandHandler<CommandType>
(命令类型不同) - 调用
Handle(commandType)
此实例以运行命令 - 返回第 3 步
我需要保护程序在失去与 SQL 服务器的连接时崩溃。目前,如果应用程序失去 SQL 连接,将抛出未处理的异常EntityException - The underlying provider failed on Open
。
一旦服务器重新联机,该程序应该能够重置和恢复操作。
这个问题涉及到 Simple Injector 的使用,因为它是我的应用程序的核心,我对编写未初始化和运行状态之间的状态转换有一些想法,但想首先询问应该在哪里以一种很好的方式捕获错误使用Simple Injector 的功能 - 具体来说,我专注于装饰器,但不确定这是否正确。
对任何其他推荐架构开放,以及从更高级别捕获错误的位置来看这可能会如何,从而允许发生状态更改。
下面的代码结构
我正在使用命令/处理程序方法:
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
在应用程序启动时,所有实现的类型ICommandHandler<T>
都被注册:
public static void Bootstrap(Container container)
{
container.RegisterManyForOpenGeneric(
typeof(ICommandHandler<>),
System.AppDomain.CurrentDomain.GetAssemblies());
// bootstrap container
}
我的命令处理程序实现如下:
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
}
}
然后,我可以使用 Simple Injector 获取类型的实例,例如,将返回ICommandHandler<AddBusinessUnitCommand>
一个实例化的对象,允许我执行命令。BusinessUnitCommandHandlers
Handle()
我已经看到 Simple Injector 可以使用装饰器来包装Handle()
过程调用。
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();
}
}