Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This solution will work for Windsor 3.0 and above. It;s based on the implementation of PerWebRequest Lifestyle and makes use of the new Scoped Lifestyle introduced in Windsor 3.0.</p> <p>You need two classes...</p> <p>An implementation of <code>IHttpModule</code> to handle session management. Adding the <code>ILifetimeScope</code> object into session and disposing it again when the session expires. This is crucial to ensure that components are released properly. This is not taken care of in other solutions given here so far.</p> <pre><code>public class PerWebSessionLifestyleModule : IHttpModule { private const string key = "castle.per-web-session-lifestyle-cache"; public void Init(HttpApplication context) { var sessionState = ((SessionStateModule)context.Modules["Session"]); sessionState.End += SessionEnd; } private static void SessionEnd(object sender, EventArgs e) { var app = (HttpApplication)sender; var scope = GetScope(app.Context.Session, false); if (scope != null) { scope.Dispose(); } } internal static ILifetimeScope GetScope() { var current = HttpContext.Current; if (current == null) { throw new InvalidOperationException("HttpContext.Current is null. PerWebSessionLifestyle can only be used in ASP.Net"); } return GetScope(current.Session, true); } internal static ILifetimeScope YieldScope() { var context = HttpContext.Current; if (context == null) { return null; } var scope = GetScope(context.Session, true); if (scope != null) { context.Session.Remove(key); } return scope; } private static ILifetimeScope GetScope(HttpSessionState session, bool createIfNotPresent) { var lifetimeScope = (ILifetimeScope)session[key]; if (lifetimeScope == null &amp;&amp; createIfNotPresent) { lifetimeScope = new DefaultLifetimeScope(new ScopeCache(), null); session[key] = lifetimeScope; return lifetimeScope; } return lifetimeScope; } public void Dispose() { } } </code></pre> <p>The second class you need is an implementation of <code>IScopeAccessor</code>. This is used to bridge the gap between your HttpModule and the built in Windsor <code>ScopedLifestyleManager</code> class.</p> <pre><code>public class WebSessionScopeAccessor : IScopeAccessor { public void Dispose() { var scope = PerWebSessionLifestyleModule.YieldScope(); if (scope != null) { scope.Dispose(); } } public ILifetimeScope GetScope(CreationContext context) { return PerWebSessionLifestyleModule.GetScope(); } } </code></pre> <p>Two <code>internal static</code> methods were added to <code>PerWebSessionLifestyleModule</code> to support this.</p> <p>That's it, expect to register it...</p> <pre><code>container.Register(Component .For&lt;ISometing&gt;() .ImplementedBy&lt;Something&gt;() .LifestyleScoped&lt;WebSessionScopeAccessor&gt;()); </code></pre> <p>Optionally, I wrapped this registration up into an extension method...</p> <pre><code>public static class ComponentRegistrationExtensions { public static ComponentRegistration&lt;TService&gt; LifestylePerSession&lt;TService&gt;(this ComponentRegistration&lt;TService&gt; reg) where TService : class { return reg.LifestyleScoped&lt;WebSessionScopeAccessor&gt;(); } } </code></pre> <p>So it can be called like this...</p> <pre><code>container.Register(Component .For&lt;ISometing&gt;() .ImplementedBy&lt;Something&gt;() .LifestylePerSession()); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload