生命周期每个方法调用和参数注入与Unity
我想与IoC容器(Unity)一起工作,并试图创建一个为我做一些UDP通信的库。生命周期每个方法调用和参数注入与Unity
基本上我得到3类:
-
一类UdpClientAdapter它实现了以下接口
public interface IUdpClient { Task<UdpReceiveResult> ReceiveAsync(); Task<int> SendAsync(byte[] datagram, int bytes); Task<int> SendAsync(byte[] datagram, int bytes, IPEndPoint endPoint); Task<int> SendAsync(byte[] datagram, int bytes, string hostname, int port); }
-
一类通信器,做一些编码/解码,校验和检查等,其实现了以下接口
public interface ICommunicator { Task<int> SendAsync(int command, object dataObject = null); Task<int> SendAsync(int command, IEnumerable<byte> data); Task<T> ReceiveAsync<T>(); }
-
和第三类的控制器',其实现了以下(简化的)接口
public interface IController { Task Start(); Task Stop(); Task<MachineStatus> ReadMachineStatus(); }
通信器的构造是
public Communicator(IUdpClient udpClient)
{
this.udpclient = udpClient;
}
所以IoC的容器,其实例化此类喷射 - 并创建 - 对UdpClient的依赖。 我的问题在于控制器类。由于我正在使用异步方法,因此我希望每次调用控制器的方法都可以获得自己的Communicator(因此是UdpClient)实例。我只使用container.Resolve()吗?
我的第二个问题是我将如何处理Communicator类的参数?在我的情况下,我需要设置UdpServer连接到,即IpEndPoint类型的字段。我应该只是扩展ICommunicator接口与该领域的setter或通过构造函数以某种方式传递它(如何?)。
感谢
由于我使用异步方法工作,我希望这样的控制器的方法,每一个电话都有自己的通讯
对我来说这是一个很大的气味。什么是抽象的消费者,应该只有这种抽象的一个实例。或者换一种说法,这种抽象不应该有任何明显的有状态。有状态的抽象使你的消费者变得复杂。这也可能意味着您正在通过抽象将实现细节从Communicator
泄漏到消费者中。问问你自己:每个ICommunicator
的实现都需要每个Controller
有一个实现吗?
这里有多种解决方案。您可以改变Communicator
的实现方式,使其变为无状态,以便Controller
可以与单个实例一起使用,或者 - 无法防止出现无效状态 - 在虚拟代理后面隐藏Communicator
。这种虚拟代理可以在每个方法调用上创建一个新的Communicator
。例如:
public interface CommunicatorProxy : ICommunicator
{
private readonly Func<ICommunicator> factory;
public CommunicatorProxy(Func<ICommunicator> factory) {
this.factory = factory;
}
public Task<int> SendAsync(int c, object d) => factory().SendAsync(c, d);
public Task<int> SendAsync(int c, IEnumerable<byte> d) => factory().SendAsync(c, d);
public Task<T> ReceiveAsync<T>() => factory().ReceiveAsync<T>();
}
我想我不能将其更改为无状态,因为我的通信以请求 - >应答方式工作。 如果发送一条消息,那么我期待一个答案。使用异步(或不同的线程)我不能保证,因此我想为每个请求使用自己的UdpClient。我以前只使用单个通信器实例尝试过我的实现,但它确实失败了,因为我无法保证我收到了我的请求的正确答案..至少除非我不使用某种公共缓冲区/队列 – kain
从我的理解你提出的方法对我也没有帮助。 我需要保证'Controller'的一个方法的所有发送/接收操作都由相同的Communicator处理。 例如'ReadMachineStatus()'方法由几个发送和接收操作组成。我必须确保我只收到相应方法的答案(例如,不是其他方法调用'停止'等) – kain