c# – 通用存储库和事务
发布时间:2020-12-15 08:28:11 所属栏目:百科 来源:网络整理
导读:我在MVC应用程序中实现了我的第一个Generic存储库.工作正常,但如何将存储库放在事务范围? public interface IRepositoryTEntity where TEntity : class { ListTEntity FetchAll(); IQueryableTEntity Query { get; } void Add(TEntity entity); void Delete
我在MVC应用程序中实现了我的第一个Generic存储库.工作正常,但如何将存储库放在事务范围?
public interface IRepository<TEntity> where TEntity : class { List<TEntity> FetchAll(); IQueryable<TEntity> Query { get; } void Add(TEntity entity); void Delete(TEntity entity); void Save(); } public class Repository<T> : IRepository<T> where T : class { private readonly DataContext _db; public Repository(DataContext db) { _db = db; } #region IRepository<T> Members public IQueryable<T> Query { get { return _db.GetTable<T>(); } } public List<T> FetchAll() { return Query.ToList(); } public void Add(T entity) { _db.GetTable<T>().InsertOnSubmit(entity); } public void Delete(T entity) { _db.GetTable<T>().DeleteOnSubmit(entity); } public void Save() { _db.SubmitChanges(); } #endregion } private void RegisterDependencyResolver() { var kernel = new StandardKernel(); var connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; kernel.Bind(typeof(DataContext)).ToMethod(context => new DataContext(connectionString)); kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)); DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel)); } public class AdminController : Controller { private readonly IRepository<User> _userRepository; private readonly IRepository<Order> _orderRepository; public AdminController(IRepository<User> userRepository,IRepository<Order> orderRepository) { _userRepository = userRepository; _orderRepository = orderRepository; } public ActionResult InsertUser(UserViewModel model) { //Skip Code //Do not commit data to database if _orderRepository is failed to save data _userRepository.Add(user); _userRepository.Save(); //Skip Code _orderRepository.Add(order); _orderRepository.Save(); } } 在InsertUser操作中使用Transaction作用域包装存储库代码的最佳方法是什么? 解决方法
你在这里错过了一个抽象.您应该将所有业务逻辑放在命令处理程序中,并创建一个实现事务行为的命令处理程序装饰器.
This article描述了如何做到这一点,但简而言之:
>定义ICommandHandler< TCommand>接口: public interface ICommandHandler<TCommand> { void Handle(TCommand command); } >创建定义业务操作合同的命令.命令只是DTOs(只有数据,没有行为).例如: public class ShipOrderCommand { public int OrderId { get; set; } public ShippingInfo Info { get; set; } } >实现将包含这些命令的业务逻辑/行为的命令处理程序: public class ShipOrderCommandHandler : ICommandHandler<ShipOrderCommand> { private readonly IRepository<Order> repository; public ShipOrderCommandHandler( IRepository<Order> repository) { this.repository = repository; } public void Handle(ShipOrderCommand command) { // do some useful stuf with the command and repository. } } >让你的MVC控制器依赖于ICommandHandler< T>抽象: public ShipOrderController : Controller { private readonly ICommandHandler<ShipOrderCommand> handler; public ShipOrderController( ICommandHandler<ShipOrderCommand> handler) { this.handler = handler; } public void Ship(int orderId,ShippingInfo info) { this.handler.Handle(new ShipOrderCommand { OrderId = orderId,Info = info }); } } >定义实现事务逻辑的通用装饰器: public TransactionalCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> { private ICommandHandler<TCommand> decoratedHandler; public TransactionalCommandHandlerDecorator( ICommandHandler<TCommand> decoratedHandler) { this.decoratedHandler = decoratedHandler; } public void Handle(TCommand command) { using (var scope = new TransactionScope()) { this.decoratedHandler.Handle(command); scope.Complete(); } } } >确保每个ShipOrderCommandHandler都使用TransactionalCommandHandlerDecorator进行修饰并注入ShipOrderController.您可以使用您喜欢的DI容器或手动执行此操作: protected override IController GetControllerInstance( RequestContext requestContext,Type controllerType) { if (controllerType == typeof(ShipOrderController)) { return new ShipOrderController( new TransactionalCommandHandlerDecorator<ShipOrderCommand>( new ShipOrderCommandHandler( new OrderRepository()))); } return base.GetControllerInstance(requestContext,controllerType); } 有了这个,您就可以在事务中运行所有业务逻辑,而无需业务逻辑了解这一点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |