代码之家  ›  专栏  ›  技术社区  ›  Darren Kopp

具有依赖注入的存储库和专用存储库的装饰链接

  •  1
  • Darren Kopp  · 技术社区  · 17 年前

    现在,我正试图找到一种更聪明的方法,在这个过程中,我所能做的就是在一天内用一整瓶的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>();
    

    让它返回一个封装在日志和事务修饰器中的用户存储库,但我想不出一种方法可以实现这一点。我唯一能想到的方法就是像这样实现用户存储库:

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

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

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

    3 回复  |  直到 17 年前
        1
  •  3
  •   toad    17 年前

    如果你要用 decorators 听起来不错。每个decorator都有一个带有IRepository参数的构造函数,并围绕对内部存储库的调用调用调用日志或事务代码。

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

        2
  •  1
  •   rball    17 年前

    难道你不能有一个LoggingRepository抽象基类来处理不同get、add、update、delete的日志记录,使它们成为虚拟的,然后从中继承吗?

    我不确定你想解决什么问题,尽管我认为你可能已经尝试过了?你也可以进行交易,尽管很可能你想在你的NHibernaterepository中这样做。

        3
  •  1
  •   scottm    17 年前

    This blog 看起来是解决问题的方法。它基本上是相同的设计,除了有一个受保护的iRepository之外,它是私有只读的。

    推荐文章