开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜