Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
348 views
in Technique[技术] by (71.8m points)

c# - How to pass Owin context to a Repo being injected into Api controller

I've got a MVC WebApi owin (soft hosted) project, that uses Unity for resolving controller dependencies

which look like this

public class PacientaiController : ODataController
    {
        private readonly IEntityRepo<Ent.Pacientas> repo;

        public PacientaiController(IEntityRepo<Ent.Pacientas> repo)
        {
            this.repo = repo;
        }

the problem I'm trying to solve - is how do I pass 'OwinContex' into a Repo.

public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
    {
        public PacientasEntityRepo(IOwinContext ctx)
        {
        .........

If I try to register it like this in the Startup.cs

Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()));

I get a null ref, saying that HttpContext.Current is NULL

The main idea here, is to pass the currently authenticated user to the repo, because Repo host the Logic for querying the Database, depending on the user. (say if the user is Admin, then return this data, if the user is guest - return this data)

The point being - that this is a self Host !

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Lets put aside why you have this design and concentrate to the problem: injecting the IOwinContext:

you can also get it from a HttpRequestMessage instance with the GetOwinContext method, however you also need to get a HttpRequestMessage somehow.

Unity does not support injection of the HttpRequestMessage out of the box but you can use a custom DelegatingHandler which stores the current HttpRequestMessage in the container as described here: Inject WebAPI UrlHelper into service using Autofac

The linked question is about Autofac but you can transfer it for work with Unity:

The CurrentRequest and the CurrentRequestHandler can be used from Andrew Davey's answer as it is:

public class CurrentRequest
{
    public HttpRequestMessage Value { get; set; }
}

public class CurrentRequestHandler : DelegatingHandler
{
    protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        var scope = request.GetDependencyScope();
        var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest));
        currentRequest.Value = request;
        return await base.SendAsync(request, cancellationToken);
    }
}

Then you just need to register the DelegatingHandler with:

httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler());

And register the CurrentRequest and IOwinContext in the container

container.RegisterType<CurrentRequest>(
            new HierarchicalLifetimeManager());

container.RegisterType<IOwinContext>(
    new HierarchicalLifetimeManager(),
    new InjectionFactory(c => c.Resolve<CurrentRequest>().Value.GetOwinContext()));

httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container);

Beside the custom delegation handler there are other places to hook into Web.API to capture the HttpRequestMessage for example you can create your own IHttpControllerActivator and use the ExecuteAsync method as described here: Dependency Injection in ASP.NET Web API 2


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...