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 中的忍者模块。

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

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

谢谢

4

2 回答 2

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;
        }
    }
}
于 2010-09-02T17:41:49.163 回答
1

如果您使用的是 Ninject.Web.Common,您的 app_start 文件夹中应该有一个 NinjectWebCommon.cs。该类实例化了一个包含 Ninject 内核的单例实例的 Bootstrapper 类。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
    }
}

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

网络配置:

  <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>();
}
于 2018-10-31T17:34:12.230 回答