HttpHandler属性注入使用Ninject返回null

时间:2010-09-02 17:12:16

标签: asp.net-mvc-2 ninject ninject-2

我有以下httphandler:

public class NewHandler : IHttpHandler
{
    [Inject]
    public IFile FileReader
    {
        get;
        set;
    }

    public NewHandler()
    {
    }

    public void ProcessRequest(System.Web.HttpContext context)
    {
        ....
        var something = SomeMethod(FileReader);
        ....
    }

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }
}

这是我在Global.asax中的Ninject模块。

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<IFile>().To<FileWrapper>().InSingletonScope();
    }
}

每次处理程序触发FileReader都为NULL。我错过了什么吗?这是使用Ninject进行属性注入的正确方法吗?

由于

2 个答案:

答案 0 :(得分:3)

这是使用Ninject进行属性注入的正确方法,但它不起作用。您可能正在使用NinjectMvcApplication类作为应用程序的基类,它处理控制器的依赖注入以及控制器可能使用的所有内容(服务,存储库)。但是HttpHandlers并没有被ControllerFactory实例化,所以没有任何东西可以用来注入东西。

也许有更好的方法,但我使用服务定位器来解决依赖。请参阅http://code.dortikum.net/2010/08/05/asp-net-mvc-di-with-common-service-locator-and-ninject/

更新:

尝试这样的事情:

public class NewHandler : IHttpHandler
{
    private readonly IFile _fileReader;

    public NewHandler()
    {
        _fileReader = ServiceLocator.Current.GetInstance<IFile>();
    }

    public void ProcessRequest(System.Web.HttpContext context)
    {
        ....
        var something = SomeMethod(_fileReader);
        ....
    }

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }
}

答案 1 :(得分:0)

如果您使用的是Ninject.Web.Common,则应在app_start文件夹中包含一个NinjectWebCommon.cs。该类实例化一个Bootstrapper类,其中包含Ninject内核的单例实例。 Ninject内核实际上可以在您的应用程序中的任何地方使用,这意味着它也可以在HTTP工厂类中使用。

以下是您可以继续以与使用控制器相同的方式继续使用Ninject的方法:

IHttpHandlerFactory是IHttpHandler实例的合成根,因此,您将需要创建此接口的实现,并将必需的配置元素添加到web.config。

MyHandlerFactory.cs:

public class MyHandlerFactory : IHttpHandlerFactory
{
    public bool IsReusable => false;

    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
       // the bootstrapper class uses the singleton pattern to share the Ninject Kernel across your web app's ApplicationDomain
       var kernel = new Bootstrapper().Kernel;

       // assuming you have only one IHttpHandler binding in your NinjectWebCommon.cs
       return kernel.Get<IHttpHandler>();
    }

    public void ReleaseHandler(IHttpHandler handler)
    {
       // nothing to release
    }
}

现在,为新的处理程序工厂添加必要的配置元素...

Web.config:

  <system.web>
    <httpHandlers>
      <add verb="GET" path="*.customThingImade" type="MyNamespace.MyHandlerFactory, MyAssemblyWhereIPutMyHandlerFactory, Version=1.0.0.0, Culture=neutral" />
    </httpHandlers>
  </system.web>
  <system.webServer>
    <handlers>
      <add name="MyHandlerFactory" verb="GET" path="*.customThingImade" type="MyNamespace.MyHandlerFactory, MyAssemblyWhereIPutMyHandlerFactory, Version=1.0.0.0, Culture=neutral" preCondition="integratedMode" />
    </handlers>
  </system.webServer>

最后,为您的IHttpHandler实现添加一个绑定...

NinjectWebCommon.cs:

private static void RegisterServices(IKernel kernel)
{
    // other bindings you already have

    // the binding for your handler factory
    Bind<IHttpHandler>().To<NewHandler>();
}