One Disposable Object Per HttpRequest

125 views
Skip to first unread message

Jake Gordon

unread,
Sep 14, 2014, 9:55:53 PM9/14/14
to structure...@googlegroups.com
I'm using StructureMap 3.1.1 in a .NET MVC 5 app and am struggling to get exactly one MyDataContext (which is a wrapper to abstract away MyDbContext) created for a given HttpRequest. My container has the following mapping:

ObjectFactory.Initialize(x =>
 
{
    x
.For<DbContext>().LifecycleIs(new UniquePerRequestLifecycle()).Use<MyDbContext>();
    x
.For<IDataContext>().LifecycleIs(new UniquePerRequestLifecycle()).Use<MyDataContext>();
}

As I understand it, .LifecycleIs(new UniquePerRequestLifecycle()) should cause StructureMap to new up a MyDataContext and MyDbContext only once per HttpRequest. Subsequent injections of these interfaces would ideally use this same instance. In reality I'm seeing the MyDataContext constructure called 13 times when I hit a particular controller. This appears to be the number of times that MyDataContext shows up as a dependency in all of the other nested dependencies further downstream.

My controller's constructor looks something like this:

        internal IGamingGroupViewModelBuilder gamingGroupViewModelBuilder;
       
internal IGamingGroupAccessGranter gamingGroupAccessGranter;
       
internal IGamingGroupCreator gamingGroupCreator;
       
internal IGamingGroupRetriever gamingGroupRetriever;

       
public GamingGroupController(
           
IGamingGroupViewModelBuilder gamingGroupViewModelBuilder,
           
IGamingGroupAccessGranter gamingGroupAccessGranter,
           
IGamingGroupCreator gamingGroupCreator,
           
IGamingGroupRetriever gamingGroupRetriever)
       
{
           
this.gamingGroupViewModelBuilder = gamingGroupViewModelBuilder;
           
this.gamingGroupAccessGranter = gamingGroupAccessGranter;
           
this.gamingGroupCreator = gamingGroupCreator;
           
this.gamingGroupRetriever = gamingGroupRetriever;
       
}

The implementations of these interfaces have constructors that take an IDataContext or another interface that in turn takes an IDataContext in the constructor of its implementation.

What am I don't wrong? How can I get StructureMap to provide the same implementation for all of these constructors? Thanks in advance and let me know if you need any additional clarification. I would love to help you help me!

Jeremy Miller

unread,
Sep 17, 2014, 8:05:59 AM9/17/14
to structure...@googlegroups.com
@Jake,

I'm so sorry this took so long for me to get back to you. "UniquePerRequestLifecycle" isn't what you want."UniquePerRequestLifecyle" means "give me a new one every single time I want one and don't track it"

Either go to the old HttpContext scope (boo) in StructureMap.Web, or use a nested container per HTTP request (my preference and how FubuMVC did it). Check out the https://www.nuget.org/packages/StructureMap.MVC5/ nuget for a pre-canned recipe to do just that. The *only* time that SM tracks objects and disposes them for you is either singletons at the Container level that get disposed when the Container itself is disposed or objects with the default lifecycle created within a nested container when that nested container is disposed.

I'll have a blog post some time this week on this issue, but it's taking a bit to get to it.

Thanks,

Jeremy

Jacob Gordon

unread,
Sep 17, 2014, 6:42:02 PM9/17/14
to structure...@googlegroups.com
Oh wow, thanks! I wasn't even close. I'll get this cleaned up quickly since I'm craving billions of DbContexts and that's not good. I like the idea of a container per request so long as the performance isn't terrible.

Sent from my iPhone
--
You received this message because you are subscribed to a topic in the Google Groups "structuremap-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/structuremap-users/_TMtq9bqcKY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to structuremap-us...@googlegroups.com.
To post to this group, send email to structure...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/structuremap-users/f4b9a7cd-776b-4d0b-9786-3bcb9f4fbe64%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jake Gordon

unread,
Sep 18, 2014, 10:34:52 PM9/18/14
to structure...@googlegroups.com
It might not be the preferred solution, but just adding .HttpContextScoped() solved my problem nicely. I now only get one object created and one disposed per request. For example:

For<DbContext>().HttpContextScoped().Use<MyDbContext>();

I'm sure you know this but the documentation on http://docs.structuremap.net/ is really obsolete in general... but beggars can't be choosers! I really do enjoy the product and appreciate your help. Thanks again.

Jeremy Miller

unread,
Sep 19, 2014, 3:18:12 PM9/19/14
to structure...@googlegroups.com
If you do that, it's on you to handle disposal at the end of HTTP requests. 

"the documentation on http://docs.structuremap.net/ is really obsolete in general" -- I take pull requests. I'm making progress on the 3.0 docs again this week.

Jake Gordon

unread,
Sep 19, 2014, 9:07:21 PM9/19/14
to structure...@googlegroups.com
I installed the StructureMap.MVC5 Nuget package and the only changes I made were to fill out the DefaultRegistry with all of my mappings explicitly. When I add .HttpContextScoped() I'm seeing everything getting disposed of properly. I'm just throwing a breakpoint in my constructors and in my Dispose() methods to verify and everything is working like a champ. Here is my DefaultRegistry: https://github.com/jakejgordon/NemeStats/blob/master/Source/UI/DependencyResolution/DefaultRegistry.cs

"I take pull requests. I'm making progress on the 3.0 docs again this week." -- I wish I could help but I'm pretty much brand new to StructureMap. I only mentioned the documentation in case you didn't realize that newbies who install StructureMap 3 might not be able to make it through the quick start since some of it doesn't apply to version 3. From a newbie perspective, updating the Quick Start (http://docs.structuremap.net/QuickStart.htm) would be the highest priority documentation item since that's the first place I'm going to go to figure out how to get started. I'm only trying to be helpful and definitely not complaining. I REALLY appreciate when people put out awesome products like this for FREE so thanks for everything!
Reply all
Reply to author
Forward
0 new messages