依赖注入的存储库和专用存储库的装饰器链接 [英] Decorator Chaining of Repositories and Specialized Repositories with Dependancy Injection

查看:84
本文介绍了依赖注入的存储库和专用存储库的装饰器链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我正在尝试找出一种使事情变得更聪明的方法,在这样做的过程中,我设法做到的是在一天之内使用一整瓶Exedrin。

Right now I'm trying to figure out a way to do things smarter, and in the course of doing so all i've managed to do is use a full bottle of excedrin in a single day.

假设我有一个名为IRepository的接口。

Assume i have an interface called IRepository like so.

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

并假设我有一个类似

And assume i have an implementation like

public class NHibernateRepository<T>
{
    ...
}

现在,全部是很好,我可以对存储库执行所有基本操作以支持所有CRUD功能,但是我可能需要专门的操作,所以假设我有这样的界面:

Now, all is fine and good, i can do all my basic operations against the repository to support all CRUD functionality, but i may want specialized operations, so assume i have an interface like this:

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

以及类似的实现:

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

好了,这是基本设置,现在我还想做一件事。我想透明地拥有日志记录和事务之类的东西。因此,我想做的是使用诸如Castle Windsor或StructureMap之类的依赖项注入框架,以便当我请求IRepository时,我将其包裹在LoggingRepository和TransactionRepository中,两者均实现IRepository。

Ok, so that is the basic setup, now there's one more thing that i want to do. I want to have logging and transaction and things like that all transparently. So what i would like to do is use a dependency injection framework like Castle Windsor or StructureMap so that when i ask for IRepository, i'll get it wrapped by a LoggingRepository and a TransactionRepository, both of which implement IRepository.

因此,我要执行的操作是这样的:

So, what i want to do is something like this:

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

并返回包裹在Logging和Transaction装饰器中的用户存储库,但是我不能想出一种可行的方法。我能想到的唯一方法是通过实现UserRepository来实现:

and have it return a user repository that's wrapped in the Logging and Transaction decorators, but i can't think of a way that this will ever work. The only way i can think of getting this to work is by implementing UserRepository like such:

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

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

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

This would mean that we would use Dependancy Injection to create a decorated repository and pass that into the constructor of the UserRepository and then use that as the repository in which we run operations against. This would work, but i still don't think it's ideal.

所以,我的问题是,我是对的,因为这是唯一的方法,或者我是不是正确理解这件事,或者只是一起丢失了一些东西。另外,如果您之前遇到过此问题,那么您如何解决此问题呢?

So, my question is, am I right in that this is the only way to do this, or am I not understanding this correctly or just missing something all together. Also, if you have run up against this problem before, how did you solve this problem?

推荐答案

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

If you are going to use decorators that sounds about right. Each decorator would have a constructor with an argument of IRepository and call the logging or transaction code around calls to the inner repository that it is decorating.

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

As an alternative you might consider, but that I have very little experience with is Aspect Oriented Programming. In that scenario you apply attributes to your classes that indicate what logging or transaction methods you want to use. At some point those methods get weaved into your code, this can be done as either as an extra compile step, or in the case of the SpringFramework.net at time of injection.

这篇关于依赖注入的存储库和专用存储库的装饰器链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆