如何为System.Net.Sockets.Socket创建接口以适配依赖注入容器?
针对无原生接口的类(如System.Net.Sockets.Socket)的DI适配最佳实践
现有实现的核心问题
当前的封装方案仅将ISocket作为原生Socket对象的容器,未实现真正的抽象解耦:上层业务仍然强依赖原生Socket类,无法在单元测试中做Mock,替换底层实现时也需要修改上层业务代码,没有发挥DI容器的解耦优势。
推荐方案:适配器模式(Adapter Pattern)
核心思路是根据业务需要做最小抽象,仅在接口中定义业务用到的方法/属性,不直接暴露原生类实例,适配层负责完成接口方法到原生类方法的转发。
1. 定义业务所需的抽象接口
不需要照搬Socket的所有API,只声明你业务中实际用到的成员即可:
public interface ISocket : IDisposable { void Connect(string host, int port); int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags); int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags); void Close(); bool Connected { get; } // 按需补充其他业务需要的方法、属性 }
2. 实现适配类包裹原生Socket
适配类内部持有原生Socket实例,实现ISocket接口的所有成员,转发调用到原生Socket对应的方法:
public class SocketAdapter : ISocket { private readonly Socket _nativeSocket; // 支持默认创建TCP Socket public SocketAdapter() { _nativeSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } // 支持外部传入已初始化的Socket实例 public SocketAdapter(Socket nativeSocket) { _nativeSocket = nativeSocket ?? throw new ArgumentNullException(nameof(nativeSocket)); } public bool Connected => _nativeSocket.Connected; public void Connect(string host, int port) => _nativeSocket.Connect(host, port); public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags) => _nativeSocket.Send(buffer, offset, size, socketFlags); public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags) => _nativeSocket.Receive(buffer, offset, size, socketFlags); public void Close() => _nativeSocket.Close(); public void Dispose() => _nativeSocket.Dispose(); }
3. DI注册与业务使用
容器注册和注入逻辑和现有写法基本一致,上层业务直接依赖ISocket接口即可,不需要接触原生Socket类:
// 容器注册 services.AddScoped<ISocket, SocketAdapter>(); // 业务类注入使用 public class ClassA : IClassA { private readonly ISocket _socket; public ClassA(ISocket socket) { _socket = socket; } // 业务逻辑直接调用ISocket的成员即可 }
进阶场景:动态创建多配置Socket
如果业务中需要创建不同参数的Socket(比如不同协议、不同地址族),可以额外引入工厂模式:
// 工厂接口 public interface ISocketFactory { ISocket Create(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType); } // 工厂实现 public class SocketFactory : ISocketFactory { public ISocket Create(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) { var nativeSocket = new Socket(addressFamily, socketType, protocolType); return new SocketAdapter(nativeSocket); } } // 容器注册工厂 services.AddSingleton<ISocketFactory, SocketFactory>();
业务中注入ISocketFactory即可按需创建不同配置的ISocket实例。
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

