0

私はから来て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));
        }
    }
}
4

1 に答える 1

2

回答を編集しましたのでご確認ください。これも大まかなスケッチです。お役に立てば幸いです。

namespace DeviceCreation
{
    //public enum DeviceType { DeviceA, DeviceB, DeviceC, DeviceD };
    public abstract class Device
    {
        public string Identifier { get; private set; }
        public Device(string identifier)
        {
            Identifier = identifier;
        }

        public abstract string Name();

        public virtual void Close()
        {

        }

        public string AskIdentifier()
        {
            return Identifier;   
        }

        public static string GetIdentifierPattern()
        {
            return "xyzsdfsdf";
        }
    }

    public class DeviceA : Device
    {
        public DeviceA(string identifier) : base(identifier) { }
        public override string Name()
        {
            return "DeviceA";
        }        
    }

    public class DeviceB : Device
    {
        public DeviceB(string identifier) : base(identifier) { }
        public override string Name()
        {
            return "DeviceB";
        }       

    }

    public class DeviceC : Device
    {
        public DeviceC(string identifier) : base(identifier) { }
        public override string Name()
        {
            return "DeviceC";
        }        
    }

    public class DeviceD : Device
    {
        public DeviceD(string identifier) : base(identifier) { }
        public override string Name()
        {
            return "DeviceD";
        }        
    }

    public class DeviceFactory
    {
        private static List<Type> device_table = new List<Type>() { typeof(DeviceA), typeof(DeviceB), typeof(DeviceC), typeof(DeviceD) };

        public static Device Create(Device device, string identifier)
        {
            if (!device_table.Contains(device.GetType()))
            {
                var message = string.Format("No device driver implemented for identifier {0}.", identifier);
                throw new NotImplementedException(message);
            }

            if (string.IsNullOrEmpty(identifier))
                throw new ArgumentException("No identifier selected.");

            //Try to open a device and then read identifier
            string dev_identifier;
            try
            {
                var dev = DevIOLib.Open(identifier);
                dev_identifier = dev.AskIdentifier();
                dev.Close();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error opening device {0} on {1}.", device, identifier));
            }

            var match = Regex.Match(dev_identifier, Device.GetIdentifierPattern());
            if (match.Success)
            {
                var newDevice = (Device) Activator.CreateInstance(device.GetType(), dev_identifier);
                return newDevice;
            }
            else
                throw new Exception(string.Format("Wrong device connected to identifier {0}.", identifier));
        }
    }

    public static class DevIOLib
    {
        public static Device Open(string identier)
        {
            return new DeviceA(identier);
        }
    }

    public class DeviceCreationTest
    {
        public static void Main(string[] args)
        {
            var d = new DeviceA("asdfsdf");
            DeviceFactory.Create(d, "asdfsdf");

            Console.ReadKey();

        }   
    }
}
于 2013-03-09T12:14:31.037 に答える