IDisposable在注入的存储库上 [英] IDisposable on an injected repository

查看:93
本文介绍了IDisposable在注入的存储库上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下ADO .Net存储库

I have the following ADO .Net Repository

public class Repository : IRepository, IDisposable
{
   private readonly IUnitOfWork UnitOfWork;
   private SqlConnection Connection;

   public Repository(IUnitOfWork unitOfWork, connectionString)
   {
      UnitOfWork = unitOfWork;
      Connection = new SqlConnection(connectionString);
      Connection.Open();
   }

   public MyObject FindBy(string userName)
   {
      //...Ado .Net command.ExecuteReader, etc.
   }
}

此存储库与IoC容器一起注入了域服务,其使用方式如下:

This repository is injected with an IoC container to a Domain Service and is used like so:

public class UserDomainService : IUserDomainService
{
   private readonly IRepository Repository;

   public UserDomainService(IRepository repository)
   {
      Repository = repository;
   }

   public User CreateNewUser(User user)
   {
      using(Repository)
      {
         var user = Repository.FindBy(user.UserName);
         if(user != null)
            throw new Exception("User name already exists!");

         Repository.Add(user);
         Repository.Commit();
      }
   }
}

我的想法是将Repository对象放在using语句中,以便当它完成时,连接被关闭并被销毁,但是由于Domain Service类仍然处于活动状态,并且如果对其进行第二次调用,则它将失败,因为我认为这是一个问题。仓库已经被破坏了。

The idea is that I always put the Repository object in a using statement so when it finishes, the connection is closed and disposed of but I see it as a problem since the Domain Service class is still alive and if there is a second call to it, it will fail since the repository has already been destroyed.

现在我已经完全控制了所有代码,我只想设计粗粒度的服务调用,但是整个过程中有些事情并没有

Now I have full control of all the code and I want to design only coarse grain service calls, but there's something about the whole thing that doesn't feel right.

我这样做是为了避免域服务了解存储库中的OpenConnection和CloseConnection方法。

I am doing it like this so I can avoid that the Domain Service knows about OpenConnection and CloseConnection methods in the repository.

此设计本身是不好的,还是有更好的方法呢?

Is this design inherently bad or is there a better way of doing this?

经过深思熟虑:全部当请求到达时,将在WCF级别上生成依赖关系树,当然,您可以看到在那一刻打开了连接s因为它发生在存储库的构造函数中,所以我认为它并不是那么糟糕,因为它仅在此特定调用期间才打开。我对这个假设是正确的,还是在过程的这么早就打开数据库连接而做得很糟糕?

After thought: All the dependency tree is being generated at the WCF level when a request arrives and, of course you can see that the connection is opened at that moment since it happens in the repository's constructor so I believe that it is not that bad since it is open only for the duration of this particular call. Am I right on this assumption or am I doing something terribly bad by opening the DB connection so early in the process?

推荐答案

注入

使用一个 IRepositoryFactory 来创建您需要的实例的工厂。 IRepository ,并在每次使用时进行处理。这样,域服务或工厂都不需要是一次性的。而且,重要的是,您仍然通过注入实现而不是对其进行硬编码来保持代码抽象。

Take an IRepositoryFactory so that you can create an IRepository and dispose of it each time you use it. This way, neither the domain service or the factory would need to be disposable. Also, and importantly, you keep the code abstract by still injecting the implementation as opposed to hard-coding it.

public class UserDomainService : IUserDomainService
{
   private readonly IRepositoryFactory RepositoryFactory;

   public UserDomainService(IRepositoryFactory factory)
   {
      RepositoryFactory = factory;
   }

   public User CreateNewUser(User user)
   {
      using (IRepository repository = RepositoryFactory.Create())
      {
         var user = repository.FindBy(user.UserName);
         if(user != null)
            throw new Exception("User name already exists!");

         repository.Add(user);
         repository.Commit();
      }
   }
}

您并不总是拥有注入您需要的类型。在阅读Castle Windsor(其心态为register-resolve-release)后,您会发现,如果要在应用程序的生命中不确定的时间内解决问题,建议使用Type Factories。

You don't always have to inject the type you need. On reading up on Castle Windsor (whose mindset is register-resolve-release), you find that if you want to Resolve stuff at an indeterminate time in the app's life, it is suggested to use Type Factories.

您知道您将需要一个存储库,但不知道何时。而不是要求存储库,而要求创建它们的东西。这样就保持了抽象级别,并且您没有泄漏任何实现。

You know you will need a Repository, but don't know when. Instead of asking for a repository, ask for something that creates them. The level of abstraction is thus maintained and you have not leaked any implementation.

这篇关于IDisposable在注入的存储库上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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