Factory method with DI and IoC

后端 未结 6 624
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 15:30

I am familiar with these patterns but still don\'t know how to handle following situation:

public class CarFactory
{
     public CarFactory(Dep1,Dep2,Dep3,De         


        
6条回答
  •  名媛妹妹
    2020-11-22 15:43

    First, you have a concrete factory, an IoC container could be an alternative rather than something to help you there.

    Then, just refactor the factory to not to expect a full possible parameter list in the factory constructor. This is the primary issue - why are you passing so many parameters if the factory method doesn't need them?

    I would rather pass specific parameters to the factory method

    public abstract class CarFactoryParams { }
    
    public class Car1FactoryParams : CarFactoryParams
    {
       public Car1FactoryParams(Dep1, Dep2, Dep3) 
       { 
          this.Dep1 = Dep1;
          ...
    }
    
    public class Car2FactoryParams 
          ...
    
    public class CarFactory
    {
        public ICar CreateCar( CarFactoryParams params )
        {
            if ( params is Car1FactoryParams )
            {
                var cp = (Car1FactoryParams)params;
                return new Car1( cp.Dep1, cp.Dep2, ... );
            }
            ...
            if ( params is ...
    

    By encapsulating the parameter list in a specific class you just make the client provide exactly these parameters that are required for specific factory method invocation.

    Edit:

    Unfortunately, it was not clear from your post what are these Dep1, ... and how you use them.

    I suggest following approach then that separates the factory provider from actual factory implementation. This approach is known as the Local Factory pattern:

    public class CarFactory
    {
       private static Func _provider;
    
       public static void SetProvider( Func provider )
       {
         _provider = provider;
       }
    
       public ICar CreateCar(type)
       {
         return _provider( type );
       }
    }
    

    The factory itself doesn't have any implementation, it is here to set the foundation to your domain API, where you want your car instances to be created with this API only.

    Then, in the Composition Root (somewhere near the starting point of the app where you configure your actual container), you configure the provider:

    CarFactory.SetProvider(
        type =>
        {
            switch ( type )
            {
               case A:
                 return _container.Resolve();
               case B:
                 return _container.Resolve();
               ..
        }
    );
    

    Note that this example implementation of the factory's provider uses a delegate but an interface could also be used as a specification for an actual provider.

    This implementation is basically #1 from your edited question, however, it doesn't have any particular downsides. The client still calls:

    var car = new CarFactory().CreareCar( type );
    

提交回复
热议问题