我有三个程序集A.dll
,B.dll
,C.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函数?
谢谢!
答案 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);
}
}