unitycontainer / aspnet-webapi

Unity.AspNet.WebApi package
Apache License 2.0
9 stars 11 forks source link

Inject Current HttpRequestMessage thru Unity WebApi #5

Closed vazans closed 7 years ago

vazans commented 7 years ago

This is NOT an issue but a request, Put in Issue per Eugene's recommendation. Dear Unity WebApi Authors, Thanks for the great Unity WebApi package, makes my life simple!! I have a quick question, this is my setup Project: AspNet WebApi2, .netframework 4.7, Unity Asp WebAPI latest as the IOC tool I have a class like below

public class Logger: ILogger { 
private readonly HttpRequestMessage request;
// Current HttpRequestMessage to be injected by Unity
public Logger(HttpRequestMessage request)
{
    this.request = request;
} }

I would like to USE Unity/Unity WebAPI package to inject Current HttpRequestMessage thru IOC above for every request 1) what is the correct way to do this? Sample code and where to register this dependency would be helpful. 2) Can I do this registration at Appstart when there is no request? 3) I know Autofac has an extension to do this but I would like to use Unity.

Can you Please reply soon as I am stuck on this for sometime. Kindly let me know any questions. Thanks again and keep up the great work.

Thanks, Sanjev Saalaivazan

ENikS commented 7 years ago

@axelgenus could you help with this one?

axelgenus commented 7 years ago

Did you tried using the static property HttpContext.Current from System.Web? It contains the data of the request.

PS; sorry for the later answer but I am quite busy in this period at work.

vazans commented 7 years ago

@axelgenus Thanks for the reply, I tried this but not sure of the unity syntax to get this going, something like this should work in web api2 but I am not getting the syntax right, what am I missing?

container.RegisterType<HttpRequestMessage, (HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage)>(); // syntax error

essentially I want to bind a type resolution to a delegate, Any help Please.

ENikS commented 7 years ago

It looks like you are trying to register instance of HttpRequestMessage stored in HttpContext.Current.Items["MS_HttpRequestMessage"].

If I understand you correctly you should use:

var instance = (HttpRequestMessage)HttpContext.Current.Items["MS_HttpRequestMessage"];
container.RegisterInstance<HttpRequestMessage)>(instance);
vazans commented 7 years ago

Thanks @ENikS, I have tried this & does not work, Issue here we are registering a singleinstance to that type which would be null in appstart & even if I register somewhere in httppipeline, HTTPrequestmessage will resolve to the single instance that it got registered to & not to every request instance. Does my explanation make sense, if not I can explain more.

ENikS commented 7 years ago

I see your point. Unfortunately I do not know much about MVC. Perhaps if you ask on one of the MVC forums or stackoverflow it would be quicker.

ENikS commented 7 years ago

You could try this:

var Func<HttpRequestMessage> factory = () => (HttpRequestMessage)HttpContext.Current.Items["MS_HttpRequestMessage"];
container.RegisterType<HttpRequestMessage>(new DelegateInjectionFactory(factory));
axelgenus commented 7 years ago

What I meant was that you should NOT use Unity for this since HttpContext.Current is static and unique for each request context.

Taking your example:

public class Logger: ILogger { 
private readonly HttpRequest request;

public Logger()
{
    this.request = HttpContext.Current.Request;
} }
vazans commented 7 years ago

Thanks @axelgenus , this is what I have been doing now but I think it breaks the IOC rule and does not mark a clear dependency between Logger and Request which is required, Thanks again for your input. @ENikS , I think the Delegate Unity syntax should work which is what I was looking for, will test and let you know.