Comments (18)
Is this an OWIN-only app or a mix of OWIN and classic pipelines? For example, ASP.NET MVC has OWIN hooks but doesn't actually run OWIN-only - it still uses the classic ASP.NET pipeline.
from autofac.owin.
The end scenario is an ASP.NET MVC application.
Pretty similar of the default samples of ASP.NET Katana.
But I'm able to reproduce this without any MVC reference and only using OWIN (the inicial sample I posted on the issue).
from autofac.owin.
From what I remember, in ASP.NET host (i.e., IIS), OnSendingRequestHeaders
occurs far after the end of OWIN pipeline (even after Request_End
). Autofac.OWIN disposes of the lifetime scope at the end of the pipeline (as OWIN doesn't offer an opportunity to dispose something at the end of request). One can add a check whether the call is done in the context of ASP.NET pipeline and bind the disposal to ASP.NET request (this, actually, is possible), but I think this would heavily complicate things (and add unneeded dependencies).
from autofac.owin.
Indeed.. I also filed an issue on aspnet/AspNetKatana#85 becuase I don't think that's a good place to put that logic in...
But I'm not optimistic..
from autofac.owin.
@tillig, actually, I think it's possible to provide a fairly easy-to-use WebHost integration package on top of my #10, which had arisen from, I think, the same problem as @joaomatossilva has - of course, if I am not mistaken and they are running in ASP.NET pipeline.
from autofac.owin.
I'm open to suggestions or PRs, but if it needs a separate WebHost integration package just to support this, I'd be very open to someone else owning and distributing that package. We have quite a few integration packages now and it's pretty difficult to keep on top of everything. It's one of the reasons we don't have time to address some of the longer-running issues in Autofac core.
from autofac.owin.
@joaomatossilva, are you hosting your OWIN pipeline in ASP.NET/IIS? Is that your target production environment?
from autofac.owin.
from autofac.owin.
Well, then you may try to get advantage of the approach I've vouched in #10 (for similar reasons), and which is now possible with Autofac.Owin 4.1.0:
- Create your lifetime scope manually in
Application_BeginRequest
(it happens earlier that any OWIN pipeline) and save it toHttpContext
. In the same event handler register your lifetime scope for disposal with HttpContext.DisposeOnPipelineCompleted - In OWIN pipeline, use
UseAutofacLifetimeInjector
with factory (instead of container) and in that factory get your lifetime fromHttpContext
(which is available fromIOwinContext
with the following:context.Get<HttpContextBase>(typeof(HttpContextBase).FullName)
, or you can simply useHttpContext.Current
, if you don't mind about testability there).
I will migrate my own project to this solution in a few days and get back with exact code samples.
from autofac.owin.
And I see that 4.1.0 is already out there. I'll give it a try as well
from autofac.owin.
One question, this will mean that I need to change the lifetime configuration to InstancePerLifetimeScope
instead of InstancePerRequest
, right?
from autofac.owin.
This is my working sample so far..
On Global.asax
public class MvcApplication : System.Web.HttpApplication
{
public const string ScopeKey = "CustomRequestScope";
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
protected void Application_BeginRequest()
{
var context = HttpContext.Current;
ConfigureAutofac(context);
}
private IContainer BuildContainer()
{
var builder = new ContainerBuilder();
//setup the registry of the PluggableComponent
builder.RegisterType<PluggableComponent>().AsSelf().InstancePerLifetimeScope();
//setup the middleware
builder.RegisterType<SimpleMiddleware>().AsSelf();
//Register the Controllers
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build();
return container;
}
private void ConfigureAutofac(HttpContext context)
{
//configure the container and start a lifetimescope
var container = BuildContainer();
var scope = container.BeginLifetimeScope(ScopeKey);
//Save the scope on the context and register it to be disposed on the end of the context
context.Items[ScopeKey] = scope;
context.DisposeOnPipelineCompleted(scope);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
And the owin startup:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseAutofacLifetimeScopeInjector(context =>
{
var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
var scope = (ILifetimeScope) httpContext.Items[MvcApplication.ScopeKey];
return scope;
});
app.Use<SimpleMiddleware>();
app.UseAutofacMvc();
}
}
Full sample here: https://github.com/joaomatossilva/AutofacCustomLifetimeScope
from autofac.owin.
If you use Autofac.Core.Lifetime.MatchingScopeLifetimeTags.RequestLifetimeScopeTag
as the request lifetime scope tag instead of a custom tag then you can use InstancePerRequest
.
from autofac.owin.
@joaomatossilva, you should create your container in Application_Start
, not Application_BeginRequest
.
from autofac.owin.
Ah.. Of course.. it was a copy past from the Owin startup that only runs once..
from autofac.owin.
I digged a bit further, and found that the scope is not being disposed by the context.DisposeOnPipelineCompleted
but from the Autofac.Integration.Mvc.RequestLifetimeHttpModule.OnEndRequest
And that is due to the DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Does this means that in order to make this work I'll need to create a custom IDependencyResolver
?
from autofac.owin.
I've update the sample now.
I did not write an entire IDependencyResolver
, I've created a ILifetimeScopeProvider and passed it on the AutofacDependencyResolver
.
here's mine:
public class LifeTimeScopeProvider : ILifetimeScopeProvider
{
public LifeTimeScopeProvider(ILifetimeScope container)
{
ApplicationContainer = container;
}
public ILifetimeScope GetLifetimeScope(Action<ContainerBuilder> configurationAction)
{
if (HttpContext.Current == null)
{
throw new InvalidOperationException("Http Context Not Available");
}
return (ILifetimeScope)HttpContext.Current.Items[MvcApplication.ScopeKey];
}
public void EndLifetimeScope()
{
}
public ILifetimeScope ApplicationContainer { get; }
}
then I register it like this on Application_Start
:
Container = BuildContainer();
var lifeTimeScopeProvider = new LifeTimeScopeProvider(Container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(Container, lifeTimeScopeProvider));
from autofac.owin.
It sounds like with the recent changes and the ability to provide your own lifetime scope/scope provider you've figured out how to get things working for your unique app needs. I'm going to go ahead and close this issue.
from autofac.owin.
Related Issues (20)
- OwinLifetimeScopeKey configurable HOT 30
- External creation of ILifetimeScope HOT 15
- .NET Standard / .NET Core support? HOT 4
- Include the latest stable version of Microsoft.Owin (4.0.0) in dependencies HOT 6
- Autofac.Owin 4.2.0 seems to require Microsoft.Owin 3.0.0 HOT 1
- Put the registration into middlewares HOT 1
- Compatibility with Autofac v6 HOT 3
- Memory Leak Due to ThreadLocalStorage / ConcurrentBag / LifetimeScope Behavior in Owin HOT 15
- Middleware registration order is inverted during resolve HOT 4
- IAsyncDisposable HOT 1
- owin autofac middleware and controller lifetime not same one HOT 1
- 7.0.0 introduced memory leak due to async disposal issue in main Autofac HOT 10
- Nuget package cannot be installed against latest version of Autofac.
- Autofac - SingleInstance get's instantiated for every API request HOT 1
- Provide the ability to control middleware execution order in the OWIN integration HOT 3
- Move DisposeScopeOnAppDisposing from Web API OWIN integration into core OWIN integration HOT 1
- Allow DI for IAppBuilder.Run HOT 3
- Only Microsoft.Owin.Middleware HOT 2
- Middleware injection doesn't work with ACTNARS HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from autofac.owin.