1

这个问题Ninject Dependency Injection in MVC3 - Outside of a Controller与我所经历的很接近,但并不完全如此。

我有一个使用 Ninject 3 的 ASP.NET MVC3 站点,它与构造函数注入完美配合。我的所有依赖项都已解决,包括那些在 HttpContext.Current 中传递的依赖项。

我的问题是,在 global.asax 中,我启动了一个 TaskManager 类,该类定期在计时器上执行一些任务。在 TaskManager 类中,我没有控制器,所以如果我需要访问我的依赖项之一(比如我的错误日志服务),我使用一个可以访问内核对象的静态包装类:

var logger = MyContainer.Get<ILoggingService>();
logger.Error("error doing something...", ex);

.Get 方法只是执行一个 kernel.Get 调用来解决我的依赖。每次我在其他依赖项上使用此方法时效果都很好。但是, ILoggingService 有一个名为 MyWebHelper 的依赖项,它通过其构造函数注入,并在其构造函数中包含 HttpContext。

    public class DefaultLogger : ILoggingService
    {     
        public DefaultLogger(IRepository<Log> logRepository, IWebHelper webHelper)
        {
            _logRepository = logRepository;
            _webHelper = webHelper;
       }
    }

    public class MyWebHelper : IWebHelper
    {
      public MyWebHelper(HttpContext httpContext)
      {
          _httpContext = httpContext;
      }
    }

在我的网站的其余部分,这一切都很好,因为所有依赖项都被注入到我的 MVC 控制器中。但是,如果我手动调用我的静态包装类来获取我的依赖项,那是行不通的。我得到错误:

使用从 HttpContext 到方法的绑定激活 HttpContext 时出错

提供者返回 null。

所以,它并没有像我的 MVC 应用程序的其余部分那样给我一个 HttpContext。我希望这是有道理的,我还不是 ninject 专家,但我正在尝试......

4

1 回答 1

3

我的问题是,在 global.asax 中,我启动了一个 TaskManager 类,该类定期在计时器上执行一些任务。

正如 Phil Haack详细解释的那样,这是一个坏主意。不要在您的 Web 应用程序中执行此操作。这些重复性任务应在单独的应用程序(Windows 服务或计划定期运行的某些控制台应用程序)中完成。

现在问题是您正在运行后台线程。这些后台线程在任何用户 HTTP 请求之外运行,因此HttpContext.Current在它们内部显然是空的。因此,即使您不遵循 Phil Haack 的建议并继续在 ASP.NET 应用程序中运行后台任务,您也必须重新构建您的方法,使其不再依赖于任何 HttpContext,因为这些后台线程中没有这样的东西。

于 2012-06-13T06:23:45.243 回答