Thursday, September 18, 2014

Using StructureMap with named instances in EPiServer

If you have several classes inheriting from the same interface, and you want your business logic to choose the correct class based on a criteria, you should check out named instances in StructureMap.

For example, let's say you have the following classes:

public class Facebook : IAuthenticationStrategy
public class Google : IAuthenticationStrategy
public class Forms : IAuthenticationStrategy

We have three implementations of IAuthenticationStrategy and the role of these classes is to validate the authentication credentials for Facebook, Google and Forms authentication.

Now, let's define the criteria as an enum:
public enum AuthenticationType
{
    Facebook,
    Forms,
    Google
}

If the user selects Facbook during login, the business logic validating the authentication will receive AuthenticationType.Facebook. If Google is selected, AuthenticationType.Google is used, and so on.

How can we use named instances in StructureMap to wire all this up? Let's define all our instances of IAuthenticationStrategy in our container:

container.Configure(
    x =>
    {
       x.For<IAuthenticationStrategy>().AddInstances(i =>
       {
          i.Type<Facebook>().Named(AuthenticationType.Facebook.ToString());
          i.Type<Google>().Named(AuthenticationType.Google.ToString());
          i.Type<Forms>().Named(AuthenticationType.Forms.ToString());
       });
});

Now all we have to do is create a Factory class passing in the AuthenticationType the user has selected:

public class AuthenticationFactory : IAuthenticationFactory
{
    public IAuthenticationStrategy Create(AuthenticationType type)
    {
         return ServiceLocator.Current.GetInstance(typeof(IAuthenticationStrategy), type.ToString()) as IAuthenticationStrategy;
    }
}

Last, but not least: Here's an example of how you could use the AuthenticationFactory to receive the correct instance:

public UserAuthentication ServerValidate(UserAuthentication userAuthentication)
{
    IAuthenticationStrategy authentication = _authenticationFactory.Create(userAuthentication.Type);
    return authentication.ServerValidate(userAuthentication);
}

Simple, right?

No comments:

Post a Comment