依赖注入或工厂模式c#

时间:2018-01-25 13:18:34

标签: c# dependency-injection

我必须写一个复杂的计算器逻辑,它有4个不同的组件来计算经纪,股票价格,管理费用和其他费用。每个都有不同的逻辑和公式。

所以我决定使用Unity DI。我有一个ContainerFactoryClass,它解析所有实现IChargeCalculator接口的类,如下面TotalAnnualCostCalculator构造函数所示。

public class TotalAnnualCostCalculator
{
    private readonly IUnityContainer container;

   //Constructor
    public TotalAnnualCostCalculator()
    {
        container = ContainerFactory.InitializeContainer();
        ContainerFactory.SetupContainer(container);
    }
    public AnnualCostCharges CalculateTotalAnnualCost(Parameters product)
    {
          var calculators = container.ResolveAll<ICalculator>().ToList();
          // Invoke calcualtion method

           Parallel.ForEach(calculators, c =>
        {
            return c.CalculateAnnualCost(product);

        });
    }

}

容器工厂类: -

public static class ContainerFactory
{
    public static IUnityContainer Container { get; private set; }
    public static IUnityContainer InitializeContainer()
    {
        var container = new UnityContainer();

        RegisterDependencies(container);

        return container;
    }

    private static void RegisterDependencies(UnityContainer container)
    {
        container.RegisterType<ICalculatorStrategyFactory, CalculatorStrategyFactory>("Factory");

        container.RegisterType<IEffectiveAnnualCostCalculator, InvestmentManagementChargeCalculator>("IMCChargeCalculator",
            new InjectionConstructor(new ResolvedParameter<ICalculatorStrategyFactory>("Factory")));
        //container.RegisterType<IEffectiveAnnualCostCalculator, AdministrationChargeCalculator>("AdministrationChargeCalculator");
        container.RegisterType<IEffectiveAnnualCostCalculator, AdviceChargeCalculator>("AdviceChargeCalculator");
        container.RegisterType<IEffectiveAnnualCostCalculator, OtherChargeCalculator>("OtherChargeCalculator");

        container.RegisterType<IInvestmentManagementChargeCalculator, LumpSumIMCCalculator>("LumpSumIMCCalculator");
        container.RegisterType<IInvestmentManagementChargeCalculator, DebitOrderIMCCalculator>("DebitOrderIMCCalculator");
    }

    public static void SetupContainer(IUnityContainer container)
    {
        Container = container;
    }
}

然后,只需创建一个TotalAnnualCostCalculator实例并调用这样的方法,任何API都会消耗我的Calculator.dll。

var totalCharges = calc.CalculateTotalAnnualCost(prod);

我的代码审核员说使用工厂模式更好,因为这与Unity Framework紧密结合。

请告知

2 个答案:

答案 0 :(得分:3)

确实,don't use a DI Container。正如史蒂文在评论中所说,这似乎非常适合Composite

int counter = 0;


onCreate(...){
    SharedPreferences countPref = getSharedPreferences("Counter", Context.MODE_PRIVATE);
    counter = countPref.getInt("count", 0);
}

mBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        counter++;
        SharedPreferences countPref = getSharedPreferences("Counter", Context.MODE_PRIVATE);
        SharedPreferences.Editor editorOpenClose = countPref.edit();
        editorOpenClose.putInt("count", counter);
        editorOpenClose.apply();


        if (counter>3){
        Toast.makeText(c, "success!", Toast.LENGTH_SHORT).show();
        }

    }
});

Composition Root中,您只需public class TotalAnnualCostCalculator : ICalculator { private readonly ICalculator[] calculators; public TotalAnnualCostCalculator(params ICalculator[] calculators) { this.calculators = calculators; } public AnnualCostCharges CalculateTotalAnnualCost(Parameters product) { Parallel.ForEach(this.calculators, c => c.CalculateAnnualCost(product)); } } 了解您要使用的所有new个对象,并将其传递给ICalculator的构造函数

答案 1 :(得分:0)

注册所有IEffectiveAnnualCostCalculator(或任何接口)。 您只需要将枚举映射到相同类型的数组。

container.RegisterType<IEnumerable<IEffectiveAnnualCostCalculator>, IEffectiveAnnualCostCalculator[]>();

使用依赖注入解决:

 private IEnumerable<IEffectiveAnnualCostCalculator> calculators;

 public TotalAnnualCostCalculator(IEnumerable<IEffectiveAnnualCostCalculator> calculators)
 {
     this.calculators = calculators;
 }

public AnnualCostCharges CalculateTotalAnnualCost(Parameters product)
{
    Parallel.ForEach(this.calculators, c => c.CalculateAnnualCost(product));
}