首页 > 解决方案 > 确定在运行时在 C# 中使用什么实现

问题描述

我的代码与 4 台不同的机器(来自不同公司的机器)对话。他们每个人都做: 1. 分配 2. 存款

让我们调用机器(A,B,C,D)。

在我的代码中,如果我想从一台机器上调用 Deposit,我最终会得到类似的结果:

MyProject.A.Deposit()

我最终得到的 switch 语句基本上是这样的:

Switch(machine){
case A:
     MyProject.A.Deposit();
 break;

 case B:
     MyProject.B.Deposit();
 break;
}

代码越大,很长的命名空间和 switch 语句的问题就变得很烦人。

我的问题是:

有没有办法告诉编译器在运行时使用特定的命名空间?或者也许通过使用配置变量或具有命名空间路径的字符串。

我想要一些我可以做的事情:

Deposit();

因为我有我连接到哪台机器的信息,所以问题只是如何动态更改命名空间。

标签: c#

解决方案


是的,假设所有四台机器DispenseDeposit方法共享同一个契约,你所需要的只是创建一个它们都实现的接口

public interface IMachine
{
    void Dispense();
    void Deposit();
}

然后确保在所有机器的具体实现上实现相同的接口:

public class MachineA : IMachine
{
     public void Dispense()
     {
         // do something here
     }

     public void Deposit()
     {
         // do something here
     }
}

public class MachineB : IMachine
{
     public void Dispense()
     {
         // do something here
     }

     public void Deposit()
     {
         // do something here
     }
}

public class MachineC : IMachine
{
     public void Dispense()
     {
         // do something here
     }

     public void Deposit()
     {
         // do something here
     }
}

public class MachineD : IMachine
{
     public void Dispense()
     {
         // do something here
     }

     public void Deposit()
     {
         // do something here
     }
}

我假设您当前没有使用依赖注入或系统中没有 IoC 容器,因此为了简单起见,您可以让工厂始终IMachine为您创建实例:

public static class MachineFactory
{
     // this is assuming you are reading the machine name from AppConfig
     private static Lazy<string> _machineName = new Lazy<string>(() => ConfigurationManager.AppSettings["TargetMachine"]);

     public IMachine GetMachine()
     {
          switch(_machineName.Value)
          {
               case "MachineA":
                    return new MachineA();                    
               case "MachineB":
                    return new MachineB();
               case "MachineC":
                    return new MachineC();
               case "MachineD":
                    return new MachineD();

          }
     }
}

现在,在您的应用程序的其余部分中,每当您需要机器实例时,您所需要做的就是使用工厂,而不必担心不同的机器实现:

var machine = MachineFactory.GetMachine();

推荐阅读