如何注入到使用Ninject一些通用的asp.net HTTP处理程序?(How do I inje

2019-07-29 06:28发布

我使用Ninject一个新手,我无法弄清楚如何注入到我的通用HTTP处理程序。 我有一个MVC3项目,我都注入我的服务到控制器中,没有问题。 这是我在我的Ninject App_start类得到了注册服务:

        private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<NLSubscriber.Core.Service.Repository.INLUserRepository>().To<NLSubscriber.Core.Service.Repository.EFDAL.EFNLUserRepository>().InRequestScope();
        kernel.Bind<Neticon.Mvc.Helpers.IConfigHelper>().To<Neticon.Mvc.Helpers.AzureEnabledConfigHelper>().InSingletonScope();
        kernel.Bind<Neticon.Security.Service.IAuthenticationService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateAuthenticationService()).InRequestScope();
        kernel.Bind<Neticon.Security.Service.IMembershipService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateMembershipService()).InRequestScope();
        kernel.Bind<Neticon.Security.Service.IRoleManagerService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateRoleManagerService()).InRequestScope();

当我尝试通过使用属性注入(与[注射]属性)从我的通用处理器得到一些服务,我总是空。 这是我的处理程序看起来像:

    public class SubscriberHandler : IHttpHandler
{
    [Inject]
    public INLUserRepository userRep { get; set;}

    public void ProcessRequest(HttpContext context)
    {
        var users = userRep.GetUsers(); //userRep is always null here
    }


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

我也试图做这样的:

    readonly INLUserRepository userRep;

    public SubscriberHandler()
    {

        using (IKernel kernel = new StandardKernel(new App_Start.NJRepositoryModule()))
        {
            userRep = kernel.Get<INLUserRepository>();
        }
    }

但我发现了异常:“错误加载Ninject组件icache中没有这样的组件已注册在内核中的组件容器建议:1)如果你已经创建了KernelBase自定义子类,请确保您已经正确实施AddComponents( )方法。2)确保已不经由到的removeAll()的调用除去从容器的组件。3)确保已不小心创建多个内核“。

这是暗示我,我不应该在我的应用程序创建一个以上的内核,对吧? 我究竟做错了什么? 谢谢

Answer 1:

你可以使用依赖解析器:

public class SubscriberHandler : IHttpHandler
{
    public INLUserRepository userRep { get; private set; }

    public SubscriberHandler()
    {
        userRep = DependencyResolver.Current.GetService<INLUserRepository>();
    }

    public void ProcessRequest(HttpContext context)
    {
        var users = userRep.GetUsers(); //userRep is always null here
    }

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

我期待,因为服务定位器模式被许多人认为是一个反模式,从这个答案得到负面的反馈。

但我不知道是否NInject允许您使用构造函数注射HTTP处理程序,因为它们是由ASP.NET运行时实例。



Answer 2:

用于组合物根IHttpHandler s是IHttpHandlerFactory 。 您可以创建自定义IHttpHandlerFactory使用Ninject来创建的实例IHttpHandler 。 这样,你可以使用构造函数注入。



Answer 3:

我看到你在你的代码片段你已经在使用Ninject.Web.Common这表明有一个“RegisterServices”的方法。 你可能不知道的是NinjectWebCommon.cs它使用包含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)
{
    kernel.Bind<NLSubscriber.Core.Service.Repository.INLUserRepository>().To<NLSubscriber.Core.Service.Repository.EFDAL.EFNLUserRepository>().InRequestScope();
    kernel.Bind<Neticon.Mvc.Helpers.IConfigHelper>().To<Neticon.Mvc.Helpers.AzureEnabledConfigHelper>().InSingletonScope();
    kernel.Bind<Neticon.Security.Service.IAuthenticationService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateAuthenticationService()).InRequestScope();
    kernel.Bind<Neticon.Security.Service.IMembershipService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateMembershipService()).InRequestScope();
    kernel.Bind<Neticon.Security.Service.IRoleManagerService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateRoleManagerService()).InRequestScope();

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


文章来源: How do I inject into some generic asp.net http handler using Ninject?