Инъекция свойства HttpHandler с использованием Ninject, возвращающего ноль - PullRequest
2 голосов
/ 02 сентября 2010

У меня есть следующий 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;
        }
    }
}

Это мой модуль Ninject в Global.asax.

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

Каждый раз, когда обработчик запускает FileReader, равен NULL.Я что-то пропустил?Это правильный способ внедрения свойства с помощью Ninject?

Спасибо

Ответы [ 2 ]

3 голосов
/ 02 сентября 2010

Это правильный способ внедрения свойства с помощью Ninject, но он не будет работать. Вероятно, вы используете что-то вроде NinjectMvcApplication class в качестве базового класса для вашего приложения, которое обрабатывает внедрение зависимостей для контроллеров и всего, что могут использовать контроллеры (службы, репозитории). Но HttpHandlers не создаются экземпляром ControllerFactory, поэтому ничего не нужно делать для инъекций.

Может быть, есть лучший способ сделать это, но я использовал сервисный локатор для разрешения зависимости. Смотри http://code.dortikum.net/2010/08/05/asp-net-mvc-di-with-common-service-locator-and-ninject/.

UPDATE:

Попробуйте что-то вроде этого:

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;
        }
    }
}
0 голосов
/ 31 октября 2018

Если вы используете Ninject.Web.Common, у вас должен быть файл NinjectWebCommon.cs в папке app_start.Этот класс создает экземпляр класса 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>();
}
...