I am new to dependency injection, but happy with Ninject
and Ninject.Extensions.Logging
to [Inject]
my ILogger
wherever i need it.
However some DelegatingHandlers are spoiling all the fun.
public class HttpsHandler : DelegatingHandler
{
[Inject]
public ILogger Logger { get; set; }
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (!string.Equals(request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase))
{
Logger.Info(String.Format("{0}: is using HTTP", request.RemoteAddress());
return
Task.Factory.StartNew(
() =>
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("HTTPS Required")
});
}
return base.SendAsync(request, cancellationToken);
}
}
Could anyone point me in the right direction on how to Inject Ninject.Extensions.Logger.Nlog2 into Ilogger inside the delegatinghandlers?
Update
I think Pete got me in the right direction in the comments (thanks!).
I added the following constructor to the HttpsHandler
:
public HttpsHandler()
{
var kernel = new StandardKernel();
var logfactory = kernel.Get<ILoggerFactory>();
this.Logger = logfactory.GetCurrentClassLogger();
}
and now i've got the Logger working!
My only question left, is this the right way to do it, or is it a anti-pattern?
DelegatingHandlers
are only initialized once in Web API, at application start.
This is a known issue/design feature of Web API (I presume for performance reasons) - see the bug report here http://aspnetwebstack.codeplex.com/workitem/62.
Using a constructor initialization like you suggested yourself, would only work if you have singleton-type dependencies (that' why you logger works). Regardless, if you want to delegate the resolution to Web API DependencyResolver
you have to use GetDependencyScope()
, which can be called off the HttpRequestMessage
, as a workaround.
I posted a walkthrough on doing that with Ninject a while ago. You should use this approach to resolve your deendency, because with your current solution you have coupled Ninject & your handler, which is far from desired.
I am using this:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var service = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IFooService)) as IFooService;
// Other stuff
}
I think what you need is this.
It's the Ninject dependency resolver for MVC. Then I believe you need to use:
GlobalConfiguration.Configuration.ServiceResolver.SetResolver()
And pass in the NInject dependency resolver.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With