【问题标题】:how Dispose() works inside my Controller and Repository classesDispose() 如何在我的 Controller 和 Repository 类中工作
【发布时间】:2016-03-25 03:14:54
【问题描述】:

我正在开发 asp.net mvc-4 Web 应用程序和实体框架 5.0。现在我对 Dispose 在我的应用程序中的工作方式感到困惑。目前我有以下设置:-

-我有一个 APIRepository 类,其中包含多个使用 WebClient() 进行外部 API 调用的方法。而且我没有在这个类中定义任何 Dispose 方法。

    public class APIRepository
        {

            public string AddTicket(string title, string technichian,string account,string site,string description,string mode,string requestor)
            {

                //code goes here

                        using (var client = new WebClient())
                        {
                        }
                   return result;
            }
//code goes here
        }

-我有一个包含我的数据访问逻辑的 Repository 类,它启动了我的DbContext,我在这个类中定义了一个 Dispose 方法。

public class Repository
{

        private MyEntities my = new MyEntities();
//code goes here...
        public void Dispose()
        {
           my.Dispose();

        }

-我有一个 Controller 类,它启动两个存储库类:-

[RequireHttps]

public class ServerController : Controller
{

        Repository repository = new Repository();
        APIRepository APIrepository = new APIRepository();

//code goes here
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                repository.Dispose();

            }
            base.Dispose(disposing);
        }

现在我对我当前的项目有以下问题:-

  1. 根据我对 Dispose 工作原理的理解,当一个 action 方法调用 View 时,asp.net mvc 会自动调用我当前 Controller 类中的 Dispose 方法。它反过来调用我的存储库中的 Dispose 方法,这将确保数据库连接已关闭。那么我的理解有效吗?

  2. 在我的情况下,我是否需要在我的 APIRepository() 中有一个 Dispose 方法,正如我提到的,这个存储库只有 WebClient() 调用以与 3rd 方应用程序集成,它将返回对象或简单字符串到action方法。??

  3. 有哪些操作需要Disposed?据我所知,在我的存储库类中调用my.Dispose(); 将确保数据库连接已关闭.. 但是否还有其他操作需要处理?比如发起WebClient()或者通过我的action方法返回一个JSON?

  4. 除了返回 View 之外,还有哪些操作会调用我的 Controller 类中的 Dispose 方法?

【问题讨论】:

  • 我 100% 确定您可以通过在此站点中搜索找到您问题的所有答案,可能会分成几个问题。
  • 看来你不是继承自IDisposable
  • @Jonesopolis 现在我的 ServerController 类扩展了 Controller 类。并且Controller类实现了IDisposable接口(这些是在asp.net mvc中开箱即用的,当我创建一个新的Controller类时),然后在ServerController中我覆盖了Dispose方法..所以不知道你是什么意思通过“看来您不是从 IDisposable 继承的”???谢谢

标签: c# asp.net .net asp.net-mvc dispose


【解决方案1】:

如果你使用依赖注入,那么没有一个类将负责创建 处理注入到其中的依赖项。

而不是这个:

public class ServerController : Controller
{
    Repository repository = new Repository();
    APIRepository APIrepository = new APIRepository();

ServerController 在哪里创建它的依赖并负责处理它们,这个:

public class ServerController : Controller
{
    private readonly Repository _repository;
    private readonly APIRepository _apiRepository;

    public ServerController(Repository repository, APIRepository apiRepository)
    {
        _repository = repository;
        _apiRepository = apiRepository;
    }

现在任何创建ServerController 实例的东西都负责实例化这些对象并处理它们。那个“随便”通常是你的依赖注入容器,比如 Windsor 或 Unity。甚至更好的是,它在 ASP.NET Core 中是内置的,您无需添加单独的容器。

简短版本:容器创建您的存储库,如果需要处置,它会处置它。您甚至可以指定有关某些依赖项的生命周期的详细信息。如果它不是一次性的并且可以重复使用,那么它就是一个单例。您可以在每次需要时创建和处置一个新实例。或者,您可以创建一个与给定 Web 请求相关联的新实例。该请求使用它,然后处理它。

【讨论】:

  • 感谢您的回复,现在在我的情况下,我没有使用依赖注入,我使用的是 Repository 方法类,那么您能告诉我我的 Dispose 将如何工作吗?我不确定你是否想说我的方法不会处理对象?
  • 存储库和依赖注入并不排斥或矛盾。如果您在班级中创建存储库,则可以将其处置,但您必须处置它。使用依赖注入,您的存储库会为您创建并作为构造函数中的参数“注入”。控制器使用它,但不负责创建或处置它。实际上它是在说,“不是我的问题,只要给我我需要的东西。”如果您使用的是 DI 容器,那么它可以创建存储库,然后在控制器超出范围时将其处理掉。
  • 这是使用 Windsor 的入门教程。 github.com/castleproject/Windsor/blob/master/docs/…。几年前,当一位同事向我介绍 DI 时,DI 完全是陌生的。对我来说,这是一个巨大的“灯泡”时刻。不仅使用 DI 容器本身解决了所有问题,而且它改变了我对编写类的想法。它还促进和鼓励最佳实践,例如单一职责课程和控制反转。它就像一种催化剂,导致许多其他事情变得有意义。我超卖了吗?太棒了。
  • 现在我有点困惑..你能告诉我我的代码到底有什么问题吗?所以我可以更好地理解你的答案..
【解决方案2】:

这将确保数据库连接已关闭。那么我的理解有效吗?

在调用 dispose 方法之前,您的数据库连接已关闭。这将是一种非常罕见的情况。

在我的情况下,我是否需要在我的 APIRepository() 中有一个 Dispose 方法

仅当您在字段级别而不是方法级别管理一次性对象时。

// The method is disposing of the object
public class NotDisposable
{
  public string GetString()
  {
    string result;
    // This is disposed by the time the method exists.
    using(var disposable new Disposable)
    {
      result = disposable.GetString()
    }
    return result;
  }
}

// This class has a field that it needs to dispose
// so it inherites from IDisposable
public class Disposable : IDisposable
{
  private bool _isDisposed;
  private readonly IDisposable _somethingToManuallyDispose;

  public Disposable()
  {
    somethingToManuallyDispose = new SomethingImplementsIDisposable();
  }

  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)  
  {
    if (disposing && !_isDisposed)
    {
      _isDisposed = true;
      // Dispose Managed Resources
      if (_somethingToManuallyDispose != null)
      {
        _somethingToManuallyDispose.Dispose();
      }
    }
  }
}

但是还有其他操作需要处理吗?

上面的例子,你没有在方法中处理一个对象。

除了返回 View 之外,还有哪些动作会调用我的 Controller 类中的 Dispose 方法

那句话甚至没有意义。返回视图不会调用 Dispose。响应发送到客户端后,控制器的 MVC/API Pipeline Disposes 处理,并且仅当它实现 IDisposable 时。

请考虑阅读MSDN - Dispose PatternMSDN - Implementing a Dispose MethodMSDN - Using Objects That Implement IDisposable

【讨论】:

  • 感谢您的回复.. 但我对我们的回复有这些问题 1)“仅当您在字段级别而不是方法级别管理一次性对象时”到底是什么意思。 ?我当前实现中的第二个问题 Servercontroller 类扩展了 Controller ,并且 Controller 实现了 IDisposable 接口(这是由 asp.net mvc 开箱即用完成的),在我的情况下,我重写了 ServerController 内的 Dispose 方法,所以Dispose 在我的情况下将如何工作?我不确定我的方法是正确还是错误?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
相关资源
最近更新 更多