具有相同API

时间:2017-07-25 08:13:43

标签: c# .net class .net-assembly

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

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

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

例如,类定义了以下函数:

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中有很多函数,所以如果/ 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();
}

这是有效的,但是如何扩展它以重复使用这段代码用于所有三个程序集?即如何将MyA,MyB,MyC传入GetAPI函数?

谢谢!

2 个答案:

答案 0 :(得分:1)

我建议创建一个接口。并使用接口而不是实际的类。另一种方法是为你的每个类创建一个Abstact Class和ovverrid的所有函数

答案 1 :(得分:1)

假设你不能使用标准的OOP模式(接口,继承)来解决这个问题,你可以制作一些帮助方法来避免编写大量代码来调用你的代理。例如,下面的这些方法允许您在Api类上执行这样的表达式:

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

请注意,这会在type参数上调用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);
    }
}