简体   繁体   English

如何为串行连接包装器实现IDisposable模式

[英]How to implement IDisposable pattern for a serial connection wrapper

I am designing a C# library that uses FTDI library to manage FTDI devices and their connections. 我正在设计一个使用FTDI库来管理FTDI设备及其连接的C#库。 I model it in three levels of operations: 1. Enumerate plugged devices; 我将其分为三个层次进行建模:1.枚举插入的设备; 2. Open/Close a connection to a specific device; 2.打开/关闭与特定设备的连接; 3. Write to the device, and receive bytes from it. 3.写入设备,并从中接收字节。

Currently I have the following classes: 目前,我有以下课程:

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);
    }
}

I know about the IDisposable pattern, and I see a clear use case for it here, regarding FtdiDevice.Open() and FtdiDevice.Close() methods, but I see that usually the pattern is implemented with another , additional class. 我知道IDisposable模式,并且在这里看到了一个清晰的用例,涉及FtdiDevice.Open()FtdiDevice.Close()方法,但我通常看到该模式是由另一个附加类实现的。 I imagine something like a FtdiConnection class, to be used like this, I think: 我想像这样使用FtdiConnection类:

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

That would imply moving the Write(byte[] bytes) method to this FtdiConnection class. 这意味着将Write(byte[] bytes)方法移动到此FtdiConnection类。

I am not sure if I am in the right track, or how much sense my idea makes, and would appreciate any clarification. 我不确定我是否在正确的道路上,或者我的想法对我有多大意义,是否会澄清您将不胜感激。

I think what you want to do this: 我认为您要执行以下操作:

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

into your open method: 进入您的开放方法:

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

and use like 并使用像

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

I found out, inspired on the discussion and previous answer, the following design answers my needs. 我发现,受讨论和先前答案的启发,以下设计满足了我的需求。 I will add it here as an alternative to Gustavo's answer, and would be glad to know other alternatives. 我将在此处添加它作为Gustavo答案的替代方法,并且很高兴知道其他替代方法。

The solution principle here is to have Device.Open() to return this as the disposable, thus avoiding the need for an additional Connection class: 这里的解决方案的原则是有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();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM