Code Monkey home page Code Monkey logo

Comments (18)

tillig avatar tillig commented on July 1, 2024

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.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

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.

srogovtsev avatar srogovtsev commented on July 1, 2024

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.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

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.

srogovtsev avatar srogovtsev commented on July 1, 2024

@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.

tillig avatar tillig commented on July 1, 2024

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.

srogovtsev avatar srogovtsev commented on July 1, 2024

@joaomatossilva, are you hosting your OWIN pipeline in ASP.NET/IIS? Is that your target production environment?

from autofac.owin.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

from autofac.owin.

srogovtsev avatar srogovtsev commented on July 1, 2024

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:

  1. Create your lifetime scope manually in Application_BeginRequest (it happens earlier that any OWIN pipeline) and save it to HttpContext. In the same event handler register your lifetime scope for disposal with HttpContext.DisposeOnPipelineCompleted
  2. In OWIN pipeline, use UseAutofacLifetimeInjector with factory (instead of container) and in that factory get your lifetime from HttpContext (which is available from IOwinContext with the following: context.Get<HttpContextBase>(typeof(HttpContextBase).FullName), or you can simply use HttpContext.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.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

And I see that 4.1.0 is already out there. I'll give it a try as well

from autofac.owin.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

One question, this will mean that I need to change the lifetime configuration to InstancePerLifetimeScope instead of InstancePerRequest, right?

from autofac.owin.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

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.

tillig avatar tillig commented on July 1, 2024

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.

srogovtsev avatar srogovtsev commented on July 1, 2024

@joaomatossilva, you should create your container in Application_Start, not Application_BeginRequest.

from autofac.owin.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

Ah.. Of course.. it was a copy past from the Owin startup that only runs once..

from autofac.owin.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

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.

joaomatossilva avatar joaomatossilva commented on July 1, 2024

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.

tillig avatar tillig commented on July 1, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.