【发布时间】:2019-09-24 00:14:34
【问题描述】:
我对接下来的架构解决方案很感兴趣。
我有:
public class GenericRepository<T> : IDisposable {
public GenericRepository(ISession session){
_session = session;
};
public T InsertAsync(T entity){...};
public IQueryable<T> Read(){...};
public T UpateAsync(T entity){...};
public void DeleteAsync(T entity){...};
public Task Commit(){
return _session.Transaction.Commit();
};
public void Dispose(){
if(_session.Transaction.IsActive){
_session.Transaction.Rollback();
}
};
}
public class UserService{
public UserService(GenericRepository<User> repository){...}
public long CreateUser(string userName){
...
_repository.Commit(); // [1]
};
}
public class OrganizationService{
public OrganizationService(GenericRepository<Organization> repository){...}
public int CreateOrganization(string code){
...
_repository.Commit(); // [2]
};
}
使用如下注册:
services.AddScoped<ISession>(x => x.GetRequiredService<NHSessionProvider>().OpenSession());
services.AddScoped(typeof(GenericRepository<>));
services.AddScoped<UserService>();
services.AddScoped<OrganizationService>();
这些CreateOrganization和CreateUser可以在代码的任何部分独立使用:
public IActionResult Post([FromServices] OrganizationService service, [FromBody] string code){
service.CreateOrganization(code);
return Ok();
}
public IActionResult Post([FromServices] UserService service, [FromBody] string userName){
service.CreateUser(userName);
return Ok();
}
不过,现在我有了一项新服务:
public class MyBillingService{
public MyBillingService(GenericRepository<Contractor> repository, OrganizationService organizationService, UserService userService){...}
public int CreateNewContractor(string organizationCode, string userName){
...
_organizationService.CreateOrganization(organizationCode);
...
_userService.CreateUser(userName);// [3]
...
_repository.Commit(); // [4]
}
}
在这个实现中,CreateOrganization 和 CreateUser 有自己的事务,如果 [3] 抛出异常,那么无论如何都会创建组织。
好的,因为ISession被注册为Scoped,那么我可以从CreateOrganization和CreateUser([1]和[2])中删除_repository.Commit。在这种情况下,[4] 将负责提交所有更改。
但是当OrganizationService 和UserService 独立使用时该怎么办?毕竟,现在它们已经成为非独立服务,如果不将更改的提交委托给其他服务,就无法保存数据:
public IActionResult Post([FromServices] UserService service, [FromServices] TransactionService transaction, [FromBody] string userName){
service.CreateUser(userName);
transaction.Commit();
return Ok();
}
就这个决定而言是一个好的决定?
【问题讨论】:
-
您可以使用 Begin 和 Commit 方法实现工作单元设计模式。在 begin 方法中,您应该使用现有事务(如果已经存在)或创建一个新事务。并且 commit 方法应该提交事务。
标签: c# asp.net-core dependency-injection nhibernate architecture