公共项目中不想依赖第三方库
使用接口
1.定义中转接口
// 公共项目(Common)
namespace Common.Transfer
{
// 空接口:仅用于标记“需要中转的第三方对象”
public interface IThirdPartyTransfer
{
// 无需任何方法/属性,仅作为类型标识
}
}
- 创建包装类 创建包装类实现公共接口,内部持有第三方对象
// 业务项目(Business)
using Common.Transfer;
using ThirdParty; // 仅业务项目引用第三方库
// 包装类:实现公共接口,持有第三方对象
public class ThirdPartyDataWrapper : IThirdPartyTransfer
{
// 内部存储第三方类型的对象
public ThirdParty.DataObject InnerData { get; }
// 构造函数接收第三方对象并包装
public ThirdPartyDataWrapper(ThirdParty.DataObject data)
{
InnerData = data;
}
}
// 公共项目:中转接口对象(不依赖第三方库)
public class TransferService
{
// 接收接口对象
public void ReceiveAndRelay(IThirdPartyTransfer transferData, Action<IThirdPartyTransfer> relayAction)
{
// 仅中转,不处理(不访问InnerData,不依赖第三方类型)
relayAction(transferData);
}
}
使用泛型
如果中转逻辑简单,可通过泛型参数让公共项目 “透明” 中转第三方类型,无需定义接口,公共项目仍不依赖第三方库。
// 公共项目:用泛型定义中转方法(T为第三方类型,公共项目无需知道具体类型)
public class GenericTransferService
{
// 接收泛型对象,中转给目标方法
public void Relay<T>(T data, Action<T> targetAction)
{
// 仅中转,不处理(不依赖T的具体类型)
targetAction(data);
}
}
// 业务项目:使用时指定第三方类型(仅业务项目引用第三方库)
using ThirdParty;
public class BusinessService
{
public void DoTransfer()
{
var thirdPartyData = new ThirdParty.DataObject(); // 第三方对象
var transferService = new Common.GenericTransferService();
// 调用公共项目的泛型方法,传入第三方对象和处理逻辑
transferService.Relay(thirdPartyData, data =>
{
// 此处处理第三方对象(业务项目依赖第三方库)
ProcessData(data);
});
}
private void ProcessData(ThirdParty.DataObject data)
{
// 具体处理逻辑
}
}
使用object类型进行中转
如果对类型安全要求不高,可直接用 object 类型作为中转载体(公共项目无需引用第三方库),但需在业务项目中手动转换类型。
// 公共项目:用object中转(不依赖第三方库)
public class ObjectTransferService
{
public void Relay(object data, Action<object> targetAction)
{
// 仅中转,不处理
targetAction(data);
}
}
// 业务项目:传入第三方对象并转换
using ThirdParty;
public class BusinessService
{
public void DoTransfer()
{
var thirdPartyData = new ThirdParty.DataObject();
var transferService = new Common.ObjectTransferService();
transferService.Relay(thirdPartyData, data =>
{
// 手动转换为第三方类型(可能抛转换异常,类型不安全)
var actualData = data as ThirdParty.DataObject;
if (actualData != null)
{
ProcessData(actualData);
}
});
}
}
三者优缺点
| 方案 | 优点 | 缺点 | 使用场景 |
|---|---|---|---|
| 抽象接口包装 | 类型安全,明确中转意图,适合复杂场景 | 需要额外定义接口和包装类 | 第三方类型固定,中转逻辑可能扩展 |
| 泛型参数中转 | 简洁,类型安全,无需额外代码 | 泛型可能增加理解成本 | 中转逻辑简单,类型明确 |
| object 中转 | 实现最简单,无需额外代码 | 类型不安全,可能抛异常 | 临时调试或极简中转场景 |