最近我接到一个任务,需要将 OPC UA 组件封装成一个独立的框架类库。最终,我选择基于 .NET Framework 4.6.2 来编写,并成功实现了这个类库,甚至编写了一个 demo 用例进行测试,结果一切正常 :mrgreen:

然而,当我把生成的 DLL 发给同事时,他们的程序出现了问题 🙁 。经过排查,发现问题出在类库中使用的第三方组件 Serilog 上,导致了依赖冲突。为了解决这个问题,我将日志功能重构为使用原生的日志记录方式,最终解决了问题,程序也恢复了正常运行 😎 。

但问题似乎并未完全解决,我开始思考,是否应该尽量避免在 C# 类库中引入第三方组件,是否可以只使用原生的 .NET 功能。

在此,我向 GPT 询问了相关问题,寻求最佳实践。

GPT 给出了以下回答:

在编写 C# 类库时,确实推荐尽量减少第三方组件的依赖,尤其是在类库是面向通用用途或将被多个项目使用时。以下是一些其他需要注意的事项:


1. API设计

  • 清晰性:类库的 API 应简单易用,参数命名直观,方法职责单一。
  • 遵循规范:遵循 .NET 的命名和设计规范(如 PascalCase 的命名风格)。
  • 低耦合:设计模块化接口,确保代码之间的耦合度尽可能低。
  • 扩展性:支持用户自定义或扩展功能,例如通过依赖注入实现可配置的组件。
  • 错误处理:提供清晰的错误反馈,避免抛出模糊的异常。

2. 避免多余的依赖

  • 减少依赖数量:每增加一个依赖,就多了一层维护成本,同时增加了用户项目中可能的冲突风险。
  • 选择轻量依赖:如果必须依赖第三方组件,选择社区活跃度高、稳定性好的轻量库。
  • 可选依赖:通过接口或插件机制引入依赖,而不是硬绑定。例如,日志记录可以通过 ILogger 接口,允许用户选择 SerilogNLog

3. 考虑兼容性

  • .NET 版本:明确目标平台(.NET Framework、.NET Core、.NET Standard 或 .NET 6+)。
    • 使用 .NET Standard 提高跨平台兼容性。
    • 如果针对现代项目,推荐基于 .NET 6 或更高版本。
  • 跨平台支持:如果可能,避免直接依赖 Windows 特定的 API,增强跨平台能力。

4. 性能优化

  • 避免频繁分配:尽量减少对象的频繁分配和回收,优先考虑使用池化技术(如 ArrayPoolObjectPool)。
  • 异步优先:尽量使用异步编程模型,提升类库在高并发环境下的表现。
  • 延迟加载:仅在需要时加载资源,避免初始化时耗费过多时间。

5. 安全性

  • 参数验证:对输入参数进行严格的验证,避免潜在的安全风险。
  • 避免敏感依赖:避免使用可能带来潜在漏洞的依赖库(如长期未更新的库)。
  • 遵循加密标准:如果类库涉及到数据加密,务必使用当前推荐的加密算法。

6. 日志和调试

  • 轻量日志:提供可选的日志支持,但避免在核心功能中强制依赖日志记录。
  • 调试友好:在调试模式下提供更详细的异常信息。

7. 文档和示例

  • XML注释:为公共 API 编写完整的 XML 注释,方便生成帮助文档。
  • 使用示例:提供典型的用法示例,帮助用户快速上手。
  • ReadMe文件:在项目根目录下提供简要说明,包括安装方法和基本用法。

8. 单元测试

  • 高测试覆盖率:确保关键功能模块有单元测试覆盖,特别是边界条件和异常场景。
  • 模拟依赖:使用依赖注入和模拟库(如 Moq)隔离测试环境。
  • 持续集成:建议配置 CI/CD 管道,自动执行构建和测试。

9. 封装和发布

  • 明确程序集边界:避免泄露内部实现的细节,例如通过 internalsealed 关键字限制外部访问。
  • 版本管理:遵循 Semantic Versioning 的版本控制规范。
  • 打包为 NuGet:发布到 NuGet 包时,附带必要的依赖说明、文档和使用示例。

10. 兼容未来需求

  • 开放封闭原则:在可能的情况下,确保类库易于扩展而无需修改原有代码。
  • 观察用户反馈:根据用户反馈和社区需求,及时调整功能和优先级。

总结:编写 C# 类库是一项需要精心规划的工作,除减少第三方依赖外,还需关注 API 设计的可用性、兼容性、性能、安全性和易维护性。通过完善文档、测试和版本管理,可以进一步提高类库的可靠性和用户满意度。

最后,我终于理解了为什么 Furion 框架以“依赖少”为特点。通过合理的依赖管理和优化设计,不仅能减少潜在的冲突,还能让类库更加高效和易于维护。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *