I have the following httphandler:
public class NewHandler : IHttpHandler
{
[Inject]
public IFile FileReader
{
get;
set;
}
This is the correct way to do property injection with Ninject, but it won't work. You are probably using something like NinjectMvcApplication
class as a base class for you application, that handles dependency injection for controllers and everything controllers might use (services, repositories). But HttpHandlers are not instantiated by the ControllerFactory
so nothing takes care of injecting stuff.
Maybe there's better way to do it, but i used service locator to resolve the dependency. See http://code.dortikum.net/2010/08/05/asp-net-mvc-di-with-common-service-locator-and-ninject/.
UPDATE:
Try something like this:
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;
}
}
}
If you're using Ninject.Web.Common, you should have a NinjectWebCommon.cs in your app_start folder. That class instantiates a Bootstrapper class which contains a singleton instance of the Ninject kernel. That Ninject kernel is actually available everywhere in your app which means it's also available in HTTP factory classes.
Here's how you can continue to use Ninject in more or less the same way you're using controllers:
IHttpHandlerFactory is the composition root for IHttpHandler instances and as such you will need to create an implementation of this interface and add the necessary configuration elements to your 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
}
}
Now, add the necessary config elements for your new handler factory...
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>
Finally, add a binding for your IHttpHandler implementation...
NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
// other bindings you already have
// the binding for your handler factory
Bind<IHttpHandler>().To<NewHandler>();
}