Inject Multiple MembershipProviders with Structuremap
I have an existing ASP.NET MVC application and am using StructureMap as my IOC container of choice. Currently when a controller needs an IMembershipProvider I use StructureMap to inject a concrete instance in the controller's constructor based on the BuyerMembershipProvider configuration from my web.config file as in the below solution code:
ObjectFactory.Initialize(x =>
{
x.ForRequestedType<IMembershipService>().TheDefaultIsConcreteType<AccountMembershipService>();
x.ForRequestedType<IFormsAuthentication>().TheDefaultIsConcreteType<FormsAuthenticationService>();
x.ForRequestedType<MembershipProvider>().TheDefault.IsThis(SecurityProvider.Providers["BuyerMembershipProvider"]);
});
This works fine. However, it is bound to the "buyer" user type. Seller information is stored in a different database and will have different tables to store membership information. Essentially, I would like to be able to inject either a BuyerMembershipProvider or a SellerMembership Provider based on context and have the following in my objectfactory initialization:
x.ForRequestedType<MembershipProvider>().TheDefault.IsThis(SecurityProvider.Providers["BuyerMembershipProvider"]);
x.ForRequestedType<MembershipProvider&g开发者_运维百科t;().TheDefault.IsThis(SecurityProvider.Providers["SellerMembershipProvider"]);
Is it possible to decide between two concrete implementations when initializing the objectfactory?
Any help is greatly appreciated, Thanks in advance! JP
You could define a factory lambda expression which will do your deciding at runtime.
var securityProviderName = ConfigurationManager.AppSettings["securityProvider"];
bool requireBuyerProvider = (securityProviderName == "Buyer");
ObjectFactory.Initialize(x =>
{
x.For<MembershipProvider>().Use(c=>
{
if (requireBuyerProvider)
c.GetInstance<SellerMemberShipProvider>();
else
c.GetInstance<BuyerMembershipProvider>();
});
});
The major mechanisms in choosing between different implementations would be via
- named instance
- choosing a certain ctor dependency
- a conditional expression in StructureMap.
You can't state 2 defaults for a given type (which should be obvious), but you can name an instance and say under which circumstances you want to use it.
A named instance is defined e.g. like this:
InstanceOf<IApplicationModule>()
.Is.OfConcreteType<BusinessProcessSupport>()
.WithName("BusinessProcessSupport");
Here is an example where a named instance is used in fulfilling a certain ctor dependency:
ForRequestedType<MenuStripModule>()
.CacheBy(InstanceScope.Singleton)
.TheDefault.Is.OfConcreteType<MenuStripModule>()
.CtorDependency<ICommandInfoProvider>()
.Is(i => i.TheInstanceNamed("Functions"));
And finally you can have a look here at a (somewhat nasty) StructureMap expression that uses the conditional capabilities: http://realfiction.net/Content/Entry/142 Please note that you are using the StructureMap 2.5.* syntax. 2.6.* is out which has modified the configuration grammar to be more concise and to the point.
精彩评论