具有相同 API 的多个程序集

Multiple Assemblies with the same API

我有三个程序集,A.dllB.dllC.dll,它们都定义了一个命名空间 A、B、C 和一个 class A、B、 C.

每个程序集中的 classes 具有完全相同的 API,在各个方面都相同。

我现在需要编写一个使用所有三个程序集的应用程序,并且我正在努力寻找执行此操作的最佳方法。

例如 classes 定义了以下函数:

string GetName();

在我的应用程序中有一个匹配功能,但是如何简化实现?

A MyA = new A();
B MyB = null;
C MyC = null;

public string GetName() {
  if (MyA != null) return MyA.GetName();
  else if (MyB != null) return MyB.GetName();
  else if (MyC != null) return MyC.GetName();
}

我在这个API里面有很多功能所以一遍又一遍if/else会很乱

接口

我考虑过为 API 定义一个接口,但是 我不想添加我的应用程序和这三个程序集所依赖的另一个程序集。我也不想在任何这些程序集之间创建相互依赖关系 。这是因为程序集在其他情况下单独使用,不幸的是只允许单个程序集,这是我无法控制的。

反思

我考虑过使用反射和委托:

private void GetAPI() {
    var Api = MyA;
    Type t = Api.GetType();
    System.Reflection.MethodInfo m = t.GetMethod("GetName");
    _GetName = (GetNameDelegate)Delegate.CreateDelegate(typeof(GetNameDelegate), Api, m);
}

public string GetName() {
    return _GetName();
}

这行得通,但我如何扩展它以将这段代码重新用于所有三个程序集? IE。如何将MyA、MyB、MyC传入GetAPI函数?

谢谢!

我建议创建一个界面。并使用界面而不是实际的 class。另一种方法是创建一个 Abstact Class 并为你

的每个 class 覆盖所有函数

假设您不能使用标准的 OOP 模式(接口、继承)来解决这个问题,您可以创建一些辅助方法来避免编写大量代码来调用您的委托。例如,下面的这些方法允许您在 Api 类:

上执行这样的表达式

var nameForApiA = Wrapper.Invoke<ApiA, string>(apiA => apiA.GetName());

请注意,这会在类型参数上调用 Activator.CreateInstance,因此如果您的 API 类 具有构造函数参数,则需要以其他方式处理这些参数。

public class Wrapper
{
    public static void Invoke<TApi>(Action<TApi> method)
    {
        var instance = Activator.CreateInstance<TApi>();
        method.Invoke(instance);
    }

    public static TReturn Invoke<TApi, TReturn> (Expression<Func<TApi, TReturn>> method)
    {
        var instance = Activator.CreateInstance<TApi>();
        Func<TApi, TReturn> compiled = method.Compile();
        return compiled(instance);
    }
}