Inject dependency into DelegatingHandler

…衆ロ難τιáo~ 提交于 2019-12-19 02:03:16

问题


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?


回答1:


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.




回答2:


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
 }



回答3:


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.




回答4:


I had a similar situation and taking hints from this post and related links, I came up with following constructor injection solution that seems to work ok for me:

using Ninject.Extensions.Logging;

public static void Register(HttpConfiguration config) {

ILoggerFactory loggerFactory =
   config.DependencyResolver.GetService(typeof(ILoggerFactory))
   as ILoggerFactory;
config.MessageHandlers.Add(
   new HttpsHandler(loggerFactory.GetLogger(typeof(HttpsHandler))));

// Other codes ...

}

I am though using Ninject for WebAi 2/log4net and have installed all pertinent nuget packages



来源:https://stackoverflow.com/questions/14756519/inject-dependency-into-delegatinghandler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!