我想知道是否有人可以为我指出正确的方向,我对 C# 还很陌生,所以对我宽容点。
我的代码使用非托管 DLL,它是提供的用于与智能卡读卡器接口(interface)的 API,我无法控制 DLL,我只是想将其包装在 C# 中以使其更易于使用。到目前为止,我已经设法做到了这一点,但我现在发现需要测试此 DLL 的多个版本,这些版本的入口点相同,但参数可以不同。 p>
我尝试了一些类似的方法来组织我的包装类;
internal static class UnSafeNativeMethods
{
internal static class READER
{
internal static class SDK20
{
[DllImport(dllpath, EntryPoint = "CV_SetCommunicationType")]
internal static extern int CV_SetCommunicationType(byte type);
...
}
internal static class SDK21
{
[DllImport(dllpath, EntryPoint = "CV_SetCommunicationType")]
internal static extern int CV_SetCommunicationType(byte type);
...
}
}
}
但是在检查要使用哪个调用时,它会产生非常难看的代码;
ReaderSDK sdk = ReaderSDK.SDK20 //Could come from a argument passed in or set in an
//instantiated class
...
switch (sdk)
{
case ReaderSDK.SDK20:
UnSafeNativeMethods.READER.SDK20.CV_SetCommunicationType(0x0);
break;
case ReaderSDK.SDK21:
UnSafeNativeMethods.READER.SDK21.CV_SetCommunicationType(0x0);
break;
...
}
这对我来说似乎很困惑,想知道是否有人可以指出我正确的方向......
编辑:离开下面的评论,我想出了一些示例代码,但仍然不确定我是否走在正确的轨道上,因为我的开关仍然存在,但它现在是混凝土的一部分工厂类。
public enum ConnectionType
{
RS232 = 0x0,
USB = 0x1,
UDP = 0x2
}
interface INativeMethods
{
string Name();
void SetCommunicationType(ConnectionType type);
}
class SDK20 : INativeMethods
{
public string Name()
{
return "SDK Version 2.0";
}
// Thanks to @dzendras for this!!
public void SetCommunicationType(ConnectionType type)
{
int result = UnSafeNativeMethods.READER.SDK20.CV_SetCommunicationType((byte)type);
switch (result)
{
case 0:
return;
case 1:
throw new NotSupportedException("Communication type not supported");
case 2:
throw AnyOtherMeaningfulException("Its message");
}
}
}
class SDK21 : INativeMethods
{
public string Name()
{
return "SDK Version 2.1";
}
// Thanks to @dzendras for this!!
public void SetCommunicationType(ConnectionType type)
{
int result = UnSafeNativeMethods.READER.SDK21.CV_SetCommunicationType((byte)type);
switch (result)
{
case 0:
return;
case 1:
throw new NotSupportedException("Communication type not supported");
case 2:
throw AnyOtherMeaningfulException("Its message");
}
}
}
class NativeMethodsFactory
{
private static NativeMethodsFactory instance = new NativeMethodsFactory();
private NativeMethodsFactory()
{
}
public static NativeMethodsFactory Instance
{
get { return NativeMethodsFactory.instance; }
}
public INativeMethods Get(ReaderSDK version)
{
switch (version)
{
case ReaderSDK.SDK20:
return new SDK20();
case ReaderSDK.SDK21:
return new SDK21();
default:
return new SDK20();
}
}
}
我的方向正确吗?
这就是我现在实现对 SDK 的调用的方式...
// sdk passed in as enum, NativeMethods stored as class member.
NativeMethods = NativeMethodsFactory.Instance.Get(sdk);
...
NativeMethods.SetCommunicationType(ConnectionType.USB);
最佳答案
使用模式策略
一些关于模式的链接:
http://www.oodesign.com/strategy-pattern.html
Real World Example of the Strategy Pattern
在工厂模式的帮助下如何使用策略模式最终实现的一些示例。
INativeMethods nativeMethods = NativeMethodsFactory.Get(UnsafeSdkVersion.V1);
nativeMethods.CV_SetCommunicationType(aType);
优点:
- 通过接口(interface)和工厂解耦
- 无开关
- 易于添加新版本,所有其他代码都独立于要使用的版本。
关于c# - 如何在 C# 中管理多个版本的非托管 DLL 调用的使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11106320/