Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 890
Phil Sandler Avatar asked Oct 03 '12 15:10

Phil Sandler


2 Answers

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,

    ...
like image 65
Crixo Avatar answered Sep 19 '22 19:09

Crixo


It looks like this is possible. Take a look at this:

Example

You will need to create an ITypedFactoryComponentSelector implementation to resolve the call, and register it in the container to only resolve the calls for the classes you are interested in.

like image 26
Jace Rhea Avatar answered Sep 20 '22 19:09

Jace Rhea