基于用户输入的依赖项注入

时间:2020-07-22 10:28:30

标签: c# dependency-injection

考虑代码片段(我在示例中使用了策略模式): enter image description here

    abstract class SortStrategy
        {
           public abstract void Sort(ArrayList list);
        }
  class QuickSort : SortStrategy
    {
        public override void Sort(ArrayList list)
            {
             //...
            }
    }
  class ShellSort : SortStrategy
    {
         public override void Sort(ArrayList list)
              {
               // ....
              }
    }

和上下文:

 class SortedList
  {
    private ArrayList list = new ArrayList();
    private SortStrategy sortstrategy;

    public void SetSortStrategy(SortStrategy sortstrategy)
    {
        this.sortstrategy = sortstrategy;
    }
    public void Add(string name)
    {
        list.Add(name);
    }
    public void Sort()
    {
        sortstrategy.Sort(list);
    }
}

我的问题是最终用户通过UI并通过选择一个选项表示使用例如QuickSort的方法进行排序,但是我应该怎么做,如何设置SetSortStrategy(或在这种情况下如何进行依赖注入)< / p>

2 个答案:

答案 0 :(得分:0)

我建议对依赖项注入使用工厂模式:

public enum StrategyType
{
   A,
   B,
   C
}

public interface IStrategyFactory {
   IStrategy Create();
}

public class BasedOnUserSelStrategyFactory {

   public IStrategy Create() {
     StrategyType type = ReadUserSelectionFromFile(); // or any place stored

     switch (type) {
       case StrategyType.A:
          return di.Resolve<AStrategy>(); // resolve using di container
       case StrategyType.B:
          return di.Resolve<BStrategy>(); // resolve using di container
       case StrategyType.C:
          return di.Resolve<CStrategy>(); // resolve using di container
       default:
          throw new ArgumentException("type");
     }
   }
}

然后,在di中注册工厂:

di.Register<IStrategyFactory>().As<BasedOnUserSelStrategyFactory>();

最后:

IStrategy s = di.Resolve<IStrategyFactory>().Create();
s.MyOperation();

答案 1 :(得分:0)

我们的MORYX-Framework基于Castle.Windsor的DI允许用户在配置中配置ModuleStrategy属性。

当模块配置如下:

public class ModuleConfig : ConfigBase
{
    [DataMember, PluginStrategy(typeof(SortStrategy))]
    [ModuleStrategy(typeof(SortStrategy))]
    public string SortStrategy { get; set; }
} 

用户可以选择找到的类之一,并且SortStragy的每次导入都会自动填充一个实例。用户可以使用图形界面从下拉框中选择QuickSortShellSort以及运行时找到的任何其他实现。

[Plugin(LifeCycle.Transient, typeof(SortStrategy))]
class QuickSort : SortStrategy
{
  // ...
}

class SortedList
{
    private ArrayList list = new ArrayList();

    // injected with either QuickSort or ShellSort
    public SortStrategy Sortstrategy { get; set; }

    public void Add(string name)
    {
        list.Add(name);
    }
    public void Sort()
    {
        sortstrategy.Sort(list);
    }
}

如果您喜欢使用工厂模式,则还可以声明一个命名工厂。这可以创建如上所述注册的任何策略。

[PluginFactory(typeof(INameBasedComponentSelector))]
public interface ISortStrategyFactory
{
    SortStrategy Create(string name);

    void Destroy(SortStrategy instance);
}

如果您使用Castle.Windsor,这是我们用来在所有依赖项声明上配置重写的代码(在Apache2.0下许可): https://github.com/PHOENIXCONTACT/MORYX-Platform/blob/dev/src/Moryx.Container/LocalContainer/LocalRegistrator.cs#L34