是否可以在C#中动态指定extern别名?

时间:2014-04-30 17:24:17

标签: c# alias extern

假设您有两个包含几乎相同代码的DLL。它们之间只有微小的差异,但这些差异非常重要,需要保留不同的库。实际上,在我的特定情况下,它们是使用IKVM转换为.NET DLL的第三方Java库,因此我们无法在不重写代码的情况下将它们合并为一个。这些代表了外部供应商提供的服务器API的略有不同的版本。

当我们在代码中使用这些库时,我们被迫编写两个完全相同的类,除了我们指定的外部别名不同。

例如:

extern alias Lib1;

namespace MyNamespace
{
    public Class1
    {
        private Lib1::A a = new Lib1::A();

        public Class1()
        {
            this.a.DoStuff();
        }

        // Uses Lib1 extern alias throughout
    }
}

extern alias Lib2;

namespace MyNamespace
{
    public Class2
    {
        private Lib2::A a = new Lib2::A();

        public Class1()
        {
            this.a.DoStuff();
        }

        // Totally identical to Class1, except that it uses Lib2 extern alias throughout
    }
}

Class1中的所有代码与Class2完全相同。只是别名不同。

当我们想要更新代码时,我们被迫将代码从一个类复制到所有其他类中。然后我们只需将一个别名替换为另一个别名。

有没有一种方法可以创建单个类,并且在我们实例化类时动态指定要使用哪个extern别名?

感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

选项:

  • 针对单个DLL构建,然后只需切换DLL内容(即构建两个具有相同名称的DLL,只需更改您使用的版本)
  • 使用两个不同的实现创建一个单独的接口,其中一个与每个库进行通信

就我个人而言,我可能会选择后者。不,没有"动态外部别名"。

答案 1 :(得分:1)

我建议为Lib1.A和Lib2.A定义一个接口。

然后按如下方式实现Class2

    public MyClass
    {
        private readonly ILib _lib; 

        public Class2(ILib lib)
        {
          _lib = lib
        }
        public MyMethod()
        {
            _lib.DoStuff();
        }                
    }

您可以按以下方式调用new MyClass(new Lib1::A()).MyMethod()new MyClass(new Lib2::A()).MyMethod()

注入ILib依赖项也有助于对其进行单元测试。

答案 2 :(得分:0)

我发现你说的最好的方法是使用更高级别的命名空间......这样你可以确定在一个类中调用哪一个,然后调用正确的命名空间。

答案 3 :(得分:0)

按照Jon Skeet的回答,您可以创建一个抽象类并实现所有常见的"重复"两个类之间的代码,并将需要唯一代码的方法标记为抽象。

这样,你不会在任何地方重复代码,并且由于多态性,改变上下文并不困难。