views:

586

answers:

2

I'm having difficulty figuring out how to have StructureMap cache a non-default instance. I can cache the default instance with code like this

ForRequestedType<ISession>()
            .CacheBy(InstanceScope.HttpContext)
            .TheDefault.Is.ConstructedBy(() => ObjectFactory.GetInstance<ISessionFactory>().OpenSession());

which works as expected. And I can create a named instance fine

InstanceOf<User>().Is.ConstructedBy(() => someAwesomeConstructor()).WithName("CurrentUser");

But I'd really like to cache "CurrentUser" by session, but .CacheBy() only exists in CreatePluginFamilyExpression<> and the only way I can tell to get from CreatePluginFamilyExpression<> to IsExpression<> is by the property TheDefault, which forces me to create a default, which I don't want.

+3  A: 

this was as close as I was able to get quickly

ForRequestedType<IInterface>()
    .AddInstances(x => x
        .OfConcreteType<Implementation>()
        .WithName("foo"))
    .CacheBy(InstanceScope.HttpContext);
Matt Hinze
If this works this should be exactly what the poster requested, more than just close! :) Also would mean Freddy is wrong about a SM limitation. Lastly I think AddInstances is the approved/recommended? way of adding named instances so its better than just WithName as Jeff tried
Schneider
+1  A: 

Add a separate line with:

ForRequestedType<User>().CacheBy(...
InstanceOf<User>().Is.ConstructedBy(...

You can't currently configured caching for specific instances. The same happens if you had an IUser, and you wanted different caching for User than for another class, say PerRequestUser. In that case, if you are requesting the instance by IUser, then the same caching will always apply.

Its a current limitation of SM. The above might be what you need though. Alternatively, consider rolling your own lines that get called in the place of this expression:

() => someAwesomeConstructor()

Instead you would call:

() => GetUserCachingInSession()

And in that method, you have simple logic that retrieves it from session, if it isn't gets a new one saving it in the session.

eglasius
In this case its perfectly fine. I only have one "special" instance so only having one cache scope isn't an issue. I just didn't want a default instance as it might confuse someone if they put a User in a constructor and suddenly get the current user out of nowhere.
Jeff Mc