【问题标题】:Decorator Chaining of Repositories and Specialized Repositories with Dependancy Injection使用依赖注入的存储库和专用存储库的装饰器链接
【发布时间】:2010-10-01 04:23:46
【问题描述】:

现在我正在尝试找出一种更智能的方法,在此过程中,我设法在一天内使用一整瓶 excedrin。

假设我有一个类似 IRepository 的接口。

 public interface IRepository<T>
 {
    T Get(int id);
    void Add(T value);
    void Update(T value);
    void Delete(T value);
    ...
 }

假设我有一个像

这样的实现
public class NHibernateRepository<T>
{
    ...
}

现在,一切都很好,我可以对存储库执行所有基本操作以支持所有 CRUD 功能,但我可能需要专门的操作,所以假设我有一个这样的接口:

public interface IUserRepository : IRepository<User>
{
     IList<User> GetUsersByRole(Role role);
}

还有这样的实现:

public class UserRepository : NHibernateRepository<User>, IUserRepository
{
    ....
}

好的,这就是基本设置,现在我还想做一件事。我想要透明地进行日志记录和事务以及类似的事情。所以我想做的是使用像 Castle Windsor 或 StructureMap 这样的依赖注入框架,这样当我请求 IRepository 时,我会用 LoggingRepository 和 TransactionRepository 包装它,它们都实现了 IRepository。

所以,我想做的是这样的:

IUserRepository repository = container.Resolve< IUserRepository>();

并让它返回一个包含在 Logging 和 Transaction 装饰器中的用户存储库,但我想不出一种可行的方法。我能想到让它工作的唯一方法是像这样实现 UserRepository:

public class UserRepository : DecoratorRepository<T>, IUserRepository
{
    protected IRepository<T> Repository { get; set; }

    public UserRepository(IRepository<T> innerRepository)
    {
        Repository = innerRepository;
    }
}

这意味着我们将使用依赖注入来创建一个修饰的存储库并将其传递给 UserRepository 的构造函数,然后将其用作我们对其运行操作的存储库。这可行,但我仍然认为它不理想。

所以,我的问题是,我是否正确,这是唯一的方法,还是我没有正确理解这一点,或者只是错过了一些东西。另外,如果你之前遇到过这个问题,你是怎么解决这个问题的?

【问题讨论】:

  • 嗨,达伦。我对您如何解决这个问题非常感兴趣,因为我的情况与使用自定义查询方法关闭开放通用 Repository 类的自定义存储库和可以轻松装饰的简单开放通用存储库的情况完全相同。请告诉我……
  • @MagnusBackeus 我最终没有做修饰的存储库,因为我认为我会使用它们的大多数事情最终都用于代码的其他方面(例如事务转到UnitOfWork)。我几乎到处都注入了通用存储库,包括当我引入像IUserRepository 这样的专用存储库时,它只会注入IRepository&lt;User&gt;。但是,我从不创建与通用存储库冲突的类(即我不会创建@ 987654330@),我总是介绍新界面。
  • 有趣的方法......我已经在我的脑海中走了这条路,但总是停止思考“我应该把自定义存储库方法放在哪里”的问题,比如上面的 IList GetUsersByRole(Role role)。你通过其他接口来表达这些新的扩展方法??
  • 是的,我总是引入IUserRepository,然后注入IRepository&lt;User&gt;
  • 我之前还添加了不同的对象,例如 Query 对象,因此可能是您添加的其他对象与方法,具体取决于您在做什么。

标签: c# dependency-injection domain-driven-design repository-pattern decorator-chaining


【解决方案1】:

如果您打算使用decorators,那听起来很对。每个装饰器都有一个带有 IRepository 参数的构造函数,并围绕调用它正在装饰的内部存储库调用日志记录或事务代码。

作为替代方案,您可能会考虑,但我对面向方面编程的经验很少。在这种情况下,您将属性应用于您的类,以指示您要使用的日志记录或事务方法。在某些时候,这些方法会被编织到您的代码中,这可以作为额外的编译步骤来完成,或者在注入时 SpringFramework.net 的情况下。

【讨论】:

    【解决方案2】:

    难道您不能有一个 LoggingRepository 抽象基类来处理您的不同 Get、Add、Update、Delete 的日志记录,使它们成为虚拟然后从它们继承吗?

    虽然我认为您可能已经尝试过,但我不确定您要解决什么问题?您也可以包装事务,尽管您很可能希望在您的 NHibernateRepository 中这样做。

    【讨论】:

      猜你喜欢
      • 2018-05-02
      • 2010-11-27
      • 1970-01-01
      • 2017-06-12
      • 2012-12-23
      • 2021-01-02
      • 2016-08-16
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多