具有StructureMap(IoC)的可查询存储库-如何实现IDisposable? [英] IQueryable Repository with StructureMap (IoC) - How do i Implement IDisposable?

查看:129
本文介绍了具有StructureMap(IoC)的可查询存储库-如何实现IDisposable?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我具有以下存储库:

If i have the following Repository:

public IQueryable<User> Users()
{
   var db = new SqlDataContext();
   return db.Users;
}

我了解到只有在查询被触发时才会打开连接:

I understand that the connection is opened only when the query is fired:

public class ServiceLayer
{
   public IRepository repo;

   public ServiceLayer(IRepository injectedRepo)
   {
       this.repo = injectedRepo;
   }

   public List<User> GetUsers()
   {
       return repo.Users().ToList(); // connection opened, query fired, connection closed. (or is it??)
   }
}

如果是这种情况,我是否还需要使我的存储库实现IDisposable?

If this is the case, do i still need to make my Repository implement IDisposable?

Visual Studio Code Metrics当然认为我应该.

The Visual Studio Code Metrics certainly think i should.

我之所以使用IQueryable,是因为我将查询控制权交给了我的服务层(过滤器,分页等),因此请不要在架构上讨论使用im的事实.

I'm using IQueryable because i give control of the queries to my service layer (filters, paging, etc), so please no architectural discussions over the fact that im using it.

BTW- SqlDataContext 是我的自定义类,它扩展了Entity Framework的ObjectContext类(因此我可以拥有POCO参与者).

BTW - SqlDataContext is my custom class which extends Entity Framework's ObjectContext class (so i can have POCO parties).

问题是-我真的必须实现IDisposable吗?

So the question - do i really HAVE to implement IDisposable?

如果是这样,我不知道这怎么可能,因为每种方法共享同一个存储库实例.

If so, i have no idea how this is possible, as each method shares the same repository instance.

编辑

我正在使用Depedency Injection(StructureMap)将具体存储库注入服务层.在应用程序堆栈中遵循此模式-我正在使用ASP.NET MVC,并将具体服务注入到Controllers中.

I'm using Depedency Injection (StructureMap) to inject the concrete repository into the service layer. This pattern is followed down the app stack - i'm using ASP.NET MVC and the concrete service is injected into the Controllers.

换句话说:

  1. 用户请求网址
  2. 已创建控制器实例,该实例接收一个新的ServiceLayer实例,该实例是使用一个新的Repository实例创建的.
  3. 控制器在服务上调用方法(所有调用都使用相同的Repository实例)
  4. 请求得到处理后,控制器就消失了.

我正在使用混合模式将依赖项注入到我的控制器中,根据StructureMap文档,这将导致实例存储在HttpContext.Current.Items中.

I am using Hybrid mode to inject dependencies into my controllers, which according to the StructureMap documentation cause the instances to be stored in the HttpContext.Current.Items.

所以,我不能这样做:

   using (var repo = new Repository())
   {
      return repo.Users().ToList();
   }

因为这击败了DI的全部重点.

As this defeats the whole point of DI.

推荐答案

编辑-从Ayende Rahien获得的建议

收到了Ayende Rahien(来自Rhino Mocks,Raven,Hibernating Rhinos的声名)的电子邮件回复.

Got an email reply from Ayende Rahien (of Rhino Mocks, Raven, Hibernating Rhinos fame).

他是这样说的:

您的问题是您初始化了 您的上下文是这样的: _genericSqlServerContext = new GenericSqlServerContext(新 EntityConnection("name = EFProfDemoEntities"));

You problem is that you initialize your context like this: _genericSqlServerContext = new GenericSqlServerContext(new EntityConnection("name=EFProfDemoEntities"));

这意味着上下文不 拥有实体连接,这意味着 它不会处理它.在 一般而言,它比 具有上下文创建 联系.您可以使用以下方法做到这一点: _genericSqlServerContext = new GenericSqlServerContext("name = EFProfDemoEntities");

That means that the context doesn't own the entity connection, which means that it doesn't dispose it. In general, it is vastly preferable to have the context create the connection. You can do that by using: _genericSqlServerContext = new GenericSqlServerContext("name=EFProfDemoEntities");

这绝对是有道理的-但是,我本以为SqlServerContext的处置也将处置基础连接,所以我猜错了.

Which definetely makes sense - however i would have thought that Disposing of a SqlServerContext would also dispose of the underlying connection, guess i was wrong.

无论如何,这就是解决方案-现在一切都已得到妥善处理.

Anyway, that is the solution - now everything is getting disposed of properly.

因此,我不再需要在存储库中使用使用:

So i no longer need to do using on the repository:

public ICollection<T> FindAll<T>(Expression<Func<T, bool>> predicate, int maxRows) where T : Foo
        {
            // dont need this anymore
            //using (var cr = ObjectFactory.GetInstance<IContentRepository>())
            return _fooRepository.Find().OfType<T>().Where(predicate).Take(maxRows).ToList();

在我的基本存储库中,我实现IDisposable并只需执行以下操作:

And in my base repository, i implement IDisposable and simply do this:

Context.Dispose(); // Context is an instance of my custom sql context.

希望可以帮助别人.

这篇关于具有StructureMap(IoC)的可查询存储库-如何实现IDisposable?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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