简体   繁体   English

我应该处置非拥有的实例吗?

[英]Should I Dispose instances that are not Owned?

I'm using Autofac in a project, and I'm trying to do it right. 我在一个项目中使用Autofac,但我尝试做正确的事情。 So I've been reading the documentation and found Owned<T> . 因此,我一直在阅读文档并找到Owned<T> It seems like it's the right relationship type to use when i want to dispose something by myself - eg a DbContext which is disposable. 当我想自己处理某些事情时,似乎这是使用的正确关系类型,例如,一次性DbContext

So I changed all my injected factories Func<DbContext> to Func<Owned<DbContext>> . 因此,我将所有注入的工厂Func<DbContext>更改为Func<Owned<DbContext>>

The only thing is it feels a little dirty the Lazy<T> like behaviour and to put the Owned in the using and depending on a non framework type... 唯一的事情是感觉像Lazy<T>这样的行为有点肮脏,并根据非框架类型将Owned放在使用中...

Is it wrong to not use Owned at all? 完全不使用Owned是错误的吗?

Is there an issue in disposing instances that are not owned by my class like this? 这样处理我的班级不拥有的实例时是否存在问题?

public class MyClass
{
    private readonly Func<DbContext> _dbcFactory;

    private MyClass(Func<DbContext> dbcFactory)
    {
        _dbcFactory = dbcFactory; // nullcheck etc;
    }
    private void TheMethodWhoUpdate(String newName) 
    {
        using(var dbc  = _dbcFactory())
        {
            var ent = dbc.Table.Single(x => x.id == 3);

            end.Name = newName;
            dbc.SaveChanges();
        }
    }
}

What I was able to imagine (because I can't find a clue on the docs) is that this could lead to some performance issue, because maybe autofac will track that created DbContext instance and try to dispose it again, losing some amount of time (probably very small)... But maybe I'm wrong, and I should stick to the guide . 我能想象到的(因为我在文档上找不到线索)可能会导致一些性能问题,因为也许autofac会跟踪创建的DbContext实例并尝试再次对其进行处理,从而浪费了一些时间(可能很小)...但是也许我错了,我应该坚持使用指南

Why not just use Func<DbContext> dbcFactory like shown in your code sample? 为什么不只使用代码示例中所示的Func<DbContext> dbcFactory

You shouldn't do that, for two reasons. 您不应该这样做,有两个原因。

  1. It is the container's job to dispose of it - so let it do its job. 处置它是容器的工作-因此,让它完成它的工作。
  2. Secondly, if you register that DbContext as InstancePerLifetimeScope then multiple objects (involved in the same lifetime scope) will get the same instance of the DbContext - which is problematic if one of them disposes it out from under the other one. 其次,如果将DbContext注册为InstancePerLifetimeScope则多个对象(包含在同一生存期范围内)将获得DbContext相同实例-如果其中一个对象将其从另一个对象中移出,则是有问题的。

When having only one instance of dbcontext (or just any other class) is just not an option (there is so many reason that i won't discuss it here) it is perfectly fine to create new ones. 当仅拥有一个dbcontext实例(或仅有其他任何类)时,这不是一个选择(有很多原因我不在这里讨论),创建新实例是完全可以的。

And have a factory injected instead of just one instance is the way to obtain it while sticking to the dependency injection pattern. 在坚持依赖注入模式的同时,获得工厂注入而不只是一个实例是获得它的方法。

About the Func<Owned<T>> vs the Func<T> i just found out the hard way that let the scope do it's job it is just a bad idea. 关于Func<Owned<T>>Func<T>我刚刚发现让示波器执行其工作的艰难方法,这是一个坏主意。

I used the Func<Owned<T>> approach but even if I disposed all the owned scopes I end up with a HUGE memory leak. 我使用了Func<Owned<T>>方法,但是即使我处置了所有拥有的作用域,我最终也会遇到巨大的内存泄漏。

The way that really worked for me is to inject a factory that create the dbContext (or whatever you need for just a limited amount of time, or need to control the lifecycle). 对我而言真正有效的方法是注入一个创建dbContext的工厂(或仅在有限的时间内需要执行任何操作,或者需要控制生命周期的任何方法)。

That factory should be registered as a single instance. 该工厂应注册为一个实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM