Profile's in StructureMap have always been a huge source of problems on the list because they just don't behave exactly the way that everybody expects them to. Profile's are an irritation to me because they clutter up the internals the way that they're currently implemented and there's a distinct lack of consistency in the configuration support. The original goal of Profile's (which I only used on the very first project that used StructureMap then never again) was just to be able to switch file paths and connection strings between dev, testing, and production environments. Since there's a couple dozen different better ways to handle that scenario, we're left with what are Profile's good for. I've got two scenarios in mind:
1.) Application Mode -- flipping an application container at runtime from "connected" to "local" for instance
2.) Multi-tenancy scenarios where a request from a different type of customer or user changes out one or more registered services
Proposal:
To make things consistent, we're going to have a new ProfileRegistry that inherits from Registry but adds a couple Profile specific overrides:
public class ProfileRegistry : Registry
{
// You get to override the default when the Profile is in play
For<T>().Use<TConcrete>();
For<IFoo>().Add<OneFoo>();
For<IFoo>().Add<TwoFoo>();
// IF you call container.GetAllInstances<IFoo>() or get a type that requires IEnumerable<IFoo> while the
// Profile is active, the directive below will make the container resolve ALL the IFoo instances from the main
// container/default profile AND the ones you added above.
// THIS has been the cause of several messages to the user group over the years, and some people want it one
// way and others want it the other. This way you'll have full power over what happens
For<IFoo>().IncludeParentTypes();
}
This would be used in a normal Registry like:
public class MyRegistry : Registry
{
Profile(string name, Action<ProfileRegistry>);
Profile<T>(string name) where T : PackageRegistry, new()
}
At runtime:
*My* single biggest goal for StructureMap 3 is to drastically improve the nested container performance so Chris Patterson will stop mocking me. In order to do that, I'm trying to eliminate all the data shuffling between data structures that happens now. In regards to Profile, this means that we'll keep a completely separate "PluginGraph" for the active Profile and stack it in front of the main PluginGraph. At runtime, we'll just look to see if the Profile PluginGraph has a default, then fallback to the parent if it's not found. And of course we'll memo-ize the results.
Any thoughts?