Note that there are some explanatory texts on larger screens.

plurals
  1. POIDbConnection lifecycle management with persistent HTTP connections
    text
    copied!<p>I have a problem managing the lifetime of open database connections with StructureMap scoped to <code>HttpContext</code> when there are persistent HTTP connections in my ASP.NET MVC application, like SignalR hubs.</p> <p>My DI container, StructureMap, injects an open <code>IDbConnection</code> into several services. To ensure that these database connections are closed and properly disposed of, I call <code>ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()</code> on the <code>EndRequest</code> event.</p> <p>This works great for MVC controllers until a service requiring a database connection is injected into a SignalR hub, which keeps a persistent HTTP connection open for each client and eventually saturates the connection pool.</p> <p>If I scope <code>IDbConnection</code> to a singleton, only one connection is ever opened per-application and the pool doesn't saturate, but this is <a href="https://stackoverflow.com/a/1557614/198927">a bad idea</a> in case the connection is ever locked or times out.</p> <p>So maybe there is a way to customise the scope of database connections for my SignalR hubs? I tried resolving a service instance in each Hub method, but this still instantiates a database connection at the HttpContext scope and keeps it open for the duration of the calling client's hub connection.</p> <p>How should I manage the lifetime of database connections with StructureMap in an HTTP-scoped context when there are persistent HTTP connections around?</p> <h1>Example Code</h1> <h2>Typical Service</h2> <pre><code>public class MyService { private IDbConnection _con; public MyService(IDbConnection con) { _con = con; } public IEnumerable&lt;string&gt; GetStuff() { return _con.Select&lt;string&gt;("SELECT someString FROM SomeTable").ToList(); } } </code></pre> <h2>Typical SignalR Hub</h2> <pre><code>public class MyHub : Hub { private MyService _service; public MyHub(MyService service) { _service = service; // Oh Noes! This will open a database connection // for each Client because of HttpContext scope } public Task AddMessage() { var result = _service.GetStuff(); // ... } } </code></pre> <h2>StructureMap Configuration</h2> <pre><code>For&lt;IDbConnection&gt;() .HybridHttpOrThreadLocalScoped() .Use(() =&gt; BaseController.GetOpenConnection(MyConnectionString)); </code></pre> <h2>Global.asax.cs</h2> <pre><code>public class GlobalApplication : System.Web.HttpApplication { public GlobalApplication() { EndRequest += delegate { ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects(); }; } // ... } </code></pre>
 

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