如何为串行连接包装器

时间:2018-02-15 12:37:41

标签: c# wrapper idisposable

我正在设计一个C#库,它使用FTDI库来管理FTDI设备及其连接。我在三个操作级别中对其进行建模: 1.列举插入的设备; 2.打开/关闭与特定设备的连接; 3.写入设备,并从中接收字节。

目前我有以下课程:

public static class FtdiEnumerator
{
    public static IEnumerable<FtdiDevice> Enumerate()
    {
        FTDI ftdi = new FTDI();
        FTDI.FT_STATUS status;
        uint bufferLenght = 0;
        status = ftdi.GetNumberOfDevices(ref bufferLenght);
        FTDI.FT_DEVICE_INFO_NODE[] result = new FTDI.FT_DEVICE_INFO_NODE[bufferLenght];

        if (status != FTDI.FT_STATUS.FT_OK)
            return Enumerable.Empty<FtdiDevice>();

        status = ftdi.GetDeviceList(result);
        if (status != FTDI.FT_STATUS.FT_OK)
            return Enumerable.Empty<DispositivoFtdi>();

        return result.Where(node => node != null)
                     .Select(node => new DispositivoFtdi(node))
                     .ToArray(); ;
    }
}


public class FtdiDevice
{
    protected FT_DEVICE_INFO_NODE _node;
    protected FTDI _ftdi = new FTDI();

    public string Description => _node.Description;
    public string SerialNumber => _node.SerialNumber;

    public FtdiDevice(FT_DEVICE_INFO_NODE node)
    {
        _node = node;
    }

    public void Open(uint baudRate = 115200)
    {
        FT_STATUS status = _ftdi.OpenBySerialNumber(_node.SerialNumber);

        if (status != FT_STATUS.FT_OK)
            throw new Exception();

        status = _ftdi.SetBaudRate(baudRate);

        if (status != FT_STATUS.FT_OK)
            throw new Exception()
    }

    public void Close()
    {
        _ftdi.Close();
    }


    public void Write(byte[] bytes)
    {
        uint bytesReceived = 0;
        _ftdi.Write(bytes, bytes.Length, ref bytesReceived);
    }
}

我知道IDisposable模式,我在这里看到一个明确的用例,关于FtdiDevice.Open()FtdiDevice.Close()方法,但我看到通常模式是用另一个< / em>,附加课程。我想像这样的FtdiConnection类就像这样使用,我想:

var device = new FtdiDevice(node);
using (FtdiConnection connection = device.Open())
{
    connection.Write(bytes);
}

这意味着将Write(byte[] bytes)方法移到此FtdiConnection类。

我不确定自己是否走在正确的轨道上,或者我的想法有多大意义,并希望得到任何澄清。

2 个答案:

答案 0 :(得分:1)

我想你想做什么:

public class FtdiConnection : IDisposable
{
   private FtdiDevice device;
   public FtdiConnection(FtdiDevice device)
   {
       this.device = device;
   }
   public void Dispose()
   {
       device.Close();
   }
}

进入你的开放方法:

public FtdiConnection Open(uint baudRate = 115200)
{
    ... Open ...
    return new FtdiConnection(this);
}

并使用

var device = new FtdiDevice(node);
using (FtdiConnection connection = device.Open())
{
    connection.Write(bytes);
}

答案 1 :(得分:0)

我发现,受到讨论和之前的回答的启发,以下设计满足了我的需求。我将在此处添加它作为Gustavo答案的替代方案,并且很高兴知道其他替代方案。

这里的解决方案原则是让Device.Open()返回this作为一次性使用,从而避免需要额外的Connection类:

using System;

namespace DisposableConnection
{
    class Program
    {
        static void Main(string[] args)
        {
            var device = new Device();

            using (device.Open())
            {
                device.Write();
            }

            Console.ReadKey();
        }
    }

    public class Device : IDisposable
    {
        public Device()
        {
        }

        public IDisposable Open()
        {
            Console.WriteLine("Open!!");
            return this;
        }

        public void Close()
        {
            Console.WriteLine("Close!!");
        }

        internal void Write()
        {
            Console.WriteLine("Write!!");
            //throw new Exception();   // optional, also works
        }

        public void Dispose()
        {
            Close();
        }
    }
}