Search code examples
c#dependency-injectioncastle-windsortyped-factory-facility

Can I Use Typed Factory Facility to Return Implementation Based on (enum) Parameter?


Not sure if this is possible or not.

I need to return the correct implementation of a service based on an enum value. So the hand-coded implementation would look something like:

public enum MyEnum
{
  One,
  Two
}    

public class MyFactory
{
  public ITypeIWantToCreate Create(MyEnum type)
  {
    switch (type)
    {
       case MyEnum.One
           return new TypeIWantToCreate1();
           break;
       case MyEnum.Two
           return new TypeIWantToCreate2();
           break;
       default:
           return null;       
    }    
  }
}

The implementations that are returned have additional dependencies which will need to be injected via the container, so a hand-rolled factory won't work.

Is this possible, and if so what would the registration look like?


Solution

  • If registering your component into the container specifying the enum value as component id is an option, you may considering this approach too

     public class ByIdTypedFactoryComponentSelector : DefaultTypedFactoryComponentSelector
     {
          protected override string GetComponentName(MethodInfo method, object[] arguments)
          {
                if (method.Name == "GetById" && arguments.Length > 0 && arguments[0] is YourEnum)
                {
                     return (string)arguments[0].ToString();
                }
    
                return base.GetComponentName(method, arguments);
          }
    }
    

    than ByIdTypedFactoryComponentSelector will be used as Selector for your Typed factory

    public enum YourEnum
    {
        Option1
    }
    
    public IYourTypedFactory
    {
        IYourTyped GetById(YourEnum enumValue)
    }
    
    
    container.AddFacility<TypedFactoryFacility>();
    container.Register
    (       
        Component.For<ByIdTypedFactoryComponentSelector>(),
    
        Component.For<IYourTyped>().ImplementedBy<FooYourTyped>().Named(YourEnum.Option1.ToString()),
    
        Component.For<IYourTypedFactory>()
        .AsFactory(x => x.SelectedWith<ByIdTypedFactoryComponentSelector>())
        .LifeStyle.Singleton,
    
        ...