Resolve registered named dependency to resolve registered unnamed type

Jan 25, 2011 at 9:26 AM
Edited Jan 25, 2011 at 9:35 AM

I have multiple asp.net membership providers (for multiple Active Directory domains, see http://msdn.microsoft.com/en-us/library/ff650307.aspx). I want to abstract a membership provider away behind a IMembershipService interface that is extracted from the MembershipProvider base class. This interface is implemented by a MembershipService class that acts as a proxy for a MembershipProvider that takes this MembershipProvider as a dependency injected in the constructor.

    public interface IMembershipService
    {
        MembershipServiceUser GetUser(string username);
    }
    public class MembershipService : IMembershipService
    {
        private readonly MembershipProvider membershipProvider;

        public MembershipService(MembershipProvider membershipProvider)
        {
            Contract.Requires(membershipProvider != null);
            this.membershipProvider = membershipProvider;
        }

        public MembershipServiceUser GetUser(string username)
        {
            MembershipServiceUser result = null;

            var user = membershipProvider.GetUser(username, false);

            if (user != null)
            {
                result = new MembershipServiceUser
                {
                    UserName = user.UserName,
                    Email = user.Email,
                    ProviderUserKey = user.ProviderUserKey.ToString()
                };
            }

            return result;
        }
    }

I have also created a MembershipServiceUser class that I can serialize.

I will register the IMembershipService interface to the MembershipService class without specifying a registration name.

            Container.RegisterType<IMembershipServiceMembershipService>();

I will register each MembershipProvider instance as a named instance using the provider name by enumerating Membership.Providers.

            foreach (MembershipProvider provider in Membership.Providers)
            {
                Container.RegisterInstance<MembershipProvider>(provider.Name, provider);
            }

I would then like to be able to resolve an IMembershipService instance using the provider name (even though the IMembershipService interface itself is registered without specifying a registration name) and have Unity use that provider name to resolve the MembershipService class' dependency on a named MembershipProvider instance.

So I would like to be able to do

Container.Resolve<IMembershipService>(providerName);

without having to say anything about the MembershipProvider dependency that the MembershipService class has, because in this code I should not have any knowledge of what type IMembershipService is resolved to. In this code I only have knowledge of the IMembershipService interface and the name of the provider and should not care how this is resolved. Is this possible with Unity? Should I use some other pattern, like a factory?

cheers

Remco


Jan 26, 2011 at 5:29 AM

Unity doesn't support this out of the box, no.

The easiest thing to do is register the IMembershipService in your for loop:

foreach (MembershipProvider provider in Membership.Providers)
{
    Container.RegisterType<IMembershipService, MembershipService>(provider.Name,
        new InjectionConstructor(
new ResolvedParameter<MembershipProvider>(provider.Name))) .RegisterInstance<MembershipProvider>(provider.Name, provider); }
That gives you the effect you want with minimal extra code and no jumping through hoops.

 

Jan 26, 2011 at 8:42 AM

cool. thanks