Managing AutoFac lifetime scopes per session and request in asp.net mvc 3

前端 未结 1 1812
孤城傲影
孤城傲影 2021-01-06 04:27

I want to use AutoFac in a web application. I have the root container, a child container per session and a child container per request. I\'m trying to figure out what the/a

相关标签:
1条回答
  • 2021-01-06 05:00

    What you'll need to do is implement your own Autofac.Integration.Mvc.ILifetimeScopeProvider. This interface is what governs how/where request lifetime scopes get generated. The default one, Autofac.Integration.Mvc.RequestLifetimeScopeProvider, handles creation, disposal, and maintenance of lifetime scopes on a per-request basis.

    You can browse the code for RequestLifetimeScopeProvider here, which I highly recommend doing if you plan on undertaking this. It's the best sample I can think of containing working code showing the responsibility of one of these things.

    Your implementation of ILifetimeScopeProvider will be where you grab the session child container, spawn the request container from that, and, at the end of the request, clean up the request container. You may also want to create the session container in there if it doesn't exist. Handling cleanup/disposal of the session container may be tricky in there, but from a design perspective, it'd be nice if it was all in one place rather than some in the provider, some in your application class.

    Once you have your ILifetimeScopeProvider you'll use it when you set up your dependency resolver.

    var scopeProvider = new MyCustomLifetimeScopeProvider(container, configAction);
    var resolver = new AutofacDependencyResolver(container, scopeProvider);
    DependencyResolver.SetResolver(resolver);
    

    A couple of words of warning about the notion of a session-level scope:

    1. Your memory footprint could be huge. You're going to end up with a lifetime scope for every user on your system. While a request lifetime pops up and goes away pretty quickly, these session-level scopes will live potentially a long time. If you have a lot of session-scoped items, you're going to have a pretty good sized memory usage for each user. If people "abandon" their sessions without properly logging out, that's all the longer these things will live.
    2. Lifetime scopes and their contents aren't serializable. Looking at the code for LifetimeScope, it's not marked [Serializable]... and even if it was, the resolved objects living in there are not necessarily all marked serializable. This is important because it means your session-level lifetime scope might work on a single box with in-memory session, but if you deploy to a farm with SQL session or a session service, things will fall apart because the session can't serialize your stored scope. If you choose not to serialize the scope, then you have a different scope for each user across machines - also a potential problem.
    3. Session isn't always rehydrated. If the handler being accessed (e.g., the web form) doesn't implement IRequiresSessionState, the session won't be rehydrated (whether it's in-proc or not). Web forms and the MvcHandler implement that by default so you won't see any issues, but if you have custom handlers that require injection you'll hit some snags since "Session" won't exist for those requests.
    4. Session_End doesn't always fire. Per the docs on SessionStateModule.End, if you use out-of-proc session state you won't actually get the Session_End event, so you won't be able to clean up.

    Given the restrictions, it's generally good to try to stay away from session-stored scopes. However... if that's what you're going to do, the ILifetimeScopeProvider is the way to do it.

    0 讨论(0)
提交回复
热议问题