Question: OwinMiddleware and dependency injection


OwinMiddleware and dependency injection

Answers 0
Added at 2016-12-29 12:12

I'm trying to create an OwinMiddleware object to register in a pipeline to pull out some creds from the incoming request and apply them to a service in our service container. The result of this would be that a service that requires auth that we use in the controllers will arrive pre-authed meaning the controllers no longer have to pull out authorization headers and principals and I can remove a lot of plumbing that passes these values down several layers.

We use DependencyInjection (Microsoft.Extensions.DependencyInjection) and more importantly this authed service is scoped which means it needs to be created and destroyed per request (i.e. otherwise it might accidentally use creds from previous requests). Its set to do so via a reasonably simple implementation of IDependencyResolver that uses a ServiceCollection. The scoping works via the .BeginScope() method that I don't quite understand because I can't find the sources that actually call .BeginScope() via HttpConfiguration.IDependencyResolver, I kinda get what its up to but not entirely. It works well though.

Now the problem with the object I have inheriting from OwinMiddleware is that I can't seem to get it communicating with the relevant scoped object via the IDependencyResolver.
As I don't control the creation of the OwinMiddleware object all I can do is specify the service I want to interact with in the constructor. However this is seemingly useless because it doesn't appear to give me the same instance of object later in the pipeline than I get here (I assume because it is scoped?).

Even if I put the IDependencyResolver into the constructor I still don't get the right instance of my service. I can verify the middleware is executing.

I saw other people talking some time ago about being able to override the Invoke() function of OwinMiddleware with extra params and this solving the scope issue. This seems to make sense if the middleware is only created once as any scoped constructor dependencies would be stale by the second request. Adding the dependency during the pipeline action makes much more sense to me. However with the version of the Owin lib I have (v3) there is only:

public abstract Task Invoke(IOwinContext context);

defined on the base so as far as I can tell my only point of entry for extra services in the middleware is via the constructor. Do I need a different version? Do I need to invoke something else special to inform the pipeline to construct new instances of my middleware per request?

This blog entry seems to state this will be fixed in aspnet 5 which I believe I'm on. So how and where is it fixed?

... things are not as clean when you want to pass in a class with its own dependencies and we want to start using dependency injection. Since the constructor for OwinMiddleware requires OwinMiddleware next, we cannot simply register the middleware itself and allow our DI container to resolve its dependencies.

From what I can see, if you do need to add another dependency to your middleware you have two options: new it up with a concrete implementation (bad) or pass it in using your project’s Dependency Resolver (anti-pattern, also different between MVC and Web API). If you find any nicer methods please tell me, as I’d love to know and update this section. This has apparently been resolved for ASP.NET 5, but that doesn’t help us now…

Answers to

OwinMiddleware and dependency injection

Source Show
◀ Wstecz