【问题标题】:Shared services in Repository Pattern存储库模式中的共享服务
【发布时间】:2014-03-03 07:49:21
【问题描述】:

我想知道如何处理一个服务内部的情况让我们说ICompanyService 我需要从IUserAccountService 调用另一个方法。 ?

所以一般来说,如果没有 UserAccountCompany 就不应该存在。

IUserAccount 实现服务类如下所示:

public class UserAccountService : CrudService<UserAccount>, IUserAccountService
{
    private readonly IRepository<UserAccount> _userAccountRepository;
    private readonly IUnitOfWorkFactory _unitOfWorkFactory;

    public CompanyService(IRepository<UserAccount> userAccountRepository,
                          IUnitOfWorkFactory unitOfWorkFactory)
        : base(userAccountRepository, unitOfWorkFactory)
    {
        _userAccRepository = userAccRepository;
    }

    public int RegisterUser(UserAccount user) {

        using (var uow=_unitOfWorkFactory.Create())
        {
           // Details omitted for brievity
           var userId = _userAccountRepository.Create(user);
           uow.Commit();
           return userId;
        }
    }

   //Other service methods

}

公司ICompanyService实施:

public class CompanyService : CrudService<Company>, ICompanyService
{
    private readonly IRepository<Company> _companyRepository;
    private readonly IUnitOfWorkFactory _unitOfWorkFactory;

    public CompanyService(IRepository<Company> companyRepository,
                          IUnitOfWorkFactory unitOfWorkFactory)
        : base(companyRepository, unitOfWorkFactory)
    {
        _companyRepository= companyRepository;
    }

    public int CreateCompanyWithUserAccount(Company company) {

        using (var uow=_unitOfWorkFactory.Create())
        {
           // Some validation with the company.Details omitted for brievity
           // Here I need an instance of IUserAccountService
           // Suppose I get it through DI or IoC
           var userAccountService = IoC.Resolve<IUserAccountService>();
    ###    // Is such approach good or bad?!    ###
           var userId = userAccountService.RegisterUser(company.UserAccount);
           // Map the user id to the company
           company.UserAccount.Id = userId;
           var companyId = _companyRepository.Create(company);
           uow.Commit();
           return companyId;
        }
    }

   //Other service methods

}

ORM在仓库下是:NHibernate

【问题讨论】:

  • 问题是……?

标签: c# architecture repository-pattern unit-of-work service-layer


【解决方案1】:
  1. 您在UserAccountService 实现中似乎有错误的构造函数:public CompanyService

  2. CompanyService 实现中,您最好在构造函数中解决 IUserAccountService 依赖关系,因此您每次创建对象时都执行一次,而不是每次调用方法时。

  3. 这些依赖项没有问题。如果IUnitOfWorkFactory 实现的两个对象有问题 -> 做一个单例

【讨论】:

  • 我同意你在CompanyService 的构造函数中注入IUserAccountServiceService Locator 更好的方法,但是,在CreateCompanyWithUserAccount(Company company) 中调用RegisterUser(UserAccount user) 可能如果CreateCompanyWithUserAccount 失败,需要回滚吗?但在这种情况下,没有回滚场景。它仍然是DeleteUser(userId) 还是什么?
  • 更字面意思是这样的:在注册公司时,我为它注册了一个用户帐户,因此嵌套事务已经提交。但是,如果在创建用户帐户(已经提交)后公司注册失败,会发生什么?我应该删除它吗?
  • @Christian 如果您对 SQL 有很好的了解,您应该在 1 个事务中完成。存储库方法调用应该类似于 bool CreateUserAccountWithCompany
  • 听起来有点奇怪CreateUserAccountWithCompany 也许你的意思是CreateCompanyWithUserAccount。我认为 Company 的 UserAccount 比 UserAccount 的 Company 更合适。许多实体可能有 UserAccounts,比如说EmployeeSupplierCompany 等。所以我宁愿给他们一个 UserAccountId,而不是用可为空的 EmployeeId、SupplierId、CompanyId 等搞乱 UserAccount 表
【解决方案2】:

你可以只依赖IRepository&lt;UserAccount&gt;:

public class CompanyService : CrudService<Company>, ICompanyService
{
    private readonly IRepository<Company> _companyRepository;
    private readonly IRepository<UserAccount> _userAccountRepository;
    private readonly IUnitOfWorkFactory _unitOfWorkFactory;

    public CompanyService(IRepository<Company> companyRepository,
                          IUnitOfWorkFactory unitOfWorkFactory
                          IRepository<UserAccount> userAccountRepository)
        : base(companyRepository, unitOfWorkFactory)
    {
        _companyRepository= companyRepository;
        _userAccountRepository = userAccountRepository;
    }

    public int CreateCompanyWithUserAccount(Company company) {

        using (var uow=_unitOfWorkFactory.Create())
        {
           // Some validation with the company.Details omitted for brievity
           var userId = _userAccountRepository.Create(company.UserAccount);
           // Map the user id to the company
           company.UserAccount.Id = userId;
           var companyId = _companyRepository.Create(company);
           uow.Commit();
           return companyId;
        }
    }

   //Other service methods

}

IMO,最好依赖存储库。毕竟您的公司服务正在创建一家公司,它需要在数据库中做一些工作,这就是存储库的用途。从我在代码中可以看到,没有必要涉及UserAccountService

【讨论】:

  • 然后会是一个工作单元内的另一个工作实例吗?不知道是好是坏
  • 假设您只是查询 companyservice 应该没有问题。如果您只是查询,为什么不依赖IRepository&lt;Company&gt; 而不是服务呢?据推测,您要实现的逻辑更多地与 UserAccount 相关,而不是与公司相关。
  • 请看一下 ICompanyService 的实现
  • 您可能应该在您的CompanyService 中依赖IRepository&lt;UserAccount&gt; 并在那里进行插入。
  • 编辑了我的答案以反映这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多