具有相同 API 的多个程序集
Multiple Assemblies with the same API
我有三个程序集,A.dll
、B.dll
、C.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);
}
}
我有三个程序集,A.dll
、B.dll
、C.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);
}
}