我使用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)确保已不小心创建多个内核“。
这是暗示我,我不应该在我的应用程序创建一个以上的内核,对吧? 我究竟做错了什么? 谢谢
你可以使用依赖解析器:
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运行时实例。
用于组合物根IHttpHandler
s是IHttpHandlerFactory
。 您可以创建自定义IHttpHandlerFactory
使用Ninject来创建的实例IHttpHandler
。 这样,你可以使用构造函数注入。
我看到你在你的代码片段你已经在使用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>();
}