我来自python
新来的C#
。我正在将设备库迁移到 C#。库本身包含所有设备实现并管理它的创建。这是一些python代码:
# All supported devices must be added to this list
device_table = [DeviceA, DeviceB, DeviceC, DeviceD]
def DeviceFactory(device, identifier):
"""
Returns an open device for the given identifier. If there is no proper
driver it raises an NotImplementedError. If wrong device connected to
port a ValueError is raised
"""
assert type(identifier) == str
if device not in device_table:
# Device not found in device table, so it's not implemented
raise NotImplementedError("No device driver implemented for "
"identifier {0}.".format(identifier))
# If no identifier selected, do configuration before
if identifier == "":
raise AttributeError("No identifier selected.")
# Try to open a device and then read identifier
try:
dev = DevIOLib.open(identifier)
dev_identifier = dev.ask_identifier()
dev.close()
except Exception:
raise DeviceError("Error opening device {0} on {1}.".format(device.name(),
identifier))
# Now check if the opened device is really the right one
if re.match(device.get_idn_regex(), dev_identifier) is not None:
return device(identifier)
raise ValueError("Wrong device connected to identifier {0}.".format(identifier))
Device[A-D]
是 concreate 设备的实现。您现在可以创建设备:
concrete_device = DeviceFactory(DeviceC, "devicePortC")
我体验到这种模式效果很好,所以我想在C#
. 如您所见,实现是非常动态的。你将如何在 C# 中实现这一点?
因此,所有设备的实现和管理都应该进入一个类库,以便在其他项目中轻松使用设备。
有没有更好的方法来解决这个问题?
在 C# 的帮助下,我可以创建以下内容
public class DeviceFactory
{
private static List<Type> device_table = new List<Type>() { typeof(DeviceA)};
public static Device CreateDevice(Type deviceType, string devicePort)
{
if (string.IsNullOrEmpty(devicePort))
{
throw new ArgumentException("No identifier selected.");
}
if (!deviceType.IsSubclassOf(typeof(Device)))
{
throw new ArgumentException("Device type unknown.");
}
if (!device_table.Contains(deviceType))
{
var message = string.Format("No device driver implemented for identifier {0}.", devicePort);
throw new NotImplementedException(message);
}
string dev_identifier;
DevHandle dev_handle;
try
{
dev_handle = DevManager.Open(devicePort));
dev_identifier = dev_handle.AskIdentifier();
}
catch (Exception)
{
throw new Exception(string.Format("Error opening device on {0}.", devicePort));
}
var idn_property = deviceType.GetProperty("Identifier", BindingFlags.Static);
var match = Regex.Match(dev_identifier,
idn_property.GetValue(null, null).ToString());
if (match.Success)
{
return (VisaDevice) Activator.CreateInstance(deviceType, dev_handle);
}
else
{
dev_handle.IO.Close();
var dev_name = deviceType.GetProperty("Name", BindingFlags.Static).GetValue(null, null).ToString();
throw new Exception(string.Format("Wrong device connected to port {0}. " +
"Expected device {1}", devicePort, dev_name));
}
}
}