在MS Enterprise Library或Log4net等第三方组件上创建包装器是一个好习惯吗?

这更像是一个很好的练习题。 我想提供不同的通用库,如Logging,caching等。有很多第三方库,如MS企业库,log4Net,NCache等。

我想知道它是一个很好的做法,直接使用它们或在每个服务上创建包装器并使用DI在代码中注入该服务。

问候

这是主观的,但也取决于图书馆。

例如,log4net或NHibernate具有严格的基于接口的API 。 没有必要包装它们。 如果您之间没有任何接口,还有其他库会使您的类难以测试。 在那里写一个干净的界面可能是明智的。

有时候建议只让一小部分代码访问API,例如NHibernate或GUI库。 (注意:这不是包装,这是构建抽象层 。)另一方面,减少对log4net调用的访问没有意义,这将在整个应用程序中使用。

log4net可能是一个很好的例子,包装只是矫枉过正。 有些人遭受“包皮炎”,这是一种反模式(有时被称为“棉花包裹羊毛” ),只会产生更多的工作。 Log4net有一个如此简单的API,并且可以高度自定义,它们使它比你的包装器更好。

您会发现包装库不允许您只是与其他产品交换。 升级到更新的版本也不会更容易,而是需要更新您的包装器。

如果您希望能够交换这些概念的实现,那么创建包装器就是您的选择。

对于日志记录,已经存在可用的Common.Logging 。

使用包装接口确实使unit testing更容易,但同样重要的是,它可以使用模拟。

例如, Silverlight和WPF的PRISM框架使用名为Log的简单方法定义ILoggerFacade接口。 使用这个概念,这是我在unit testing中定义模拟记录器(使用Moq )的方法:

 var loggerMock = new Mock(MockBehavior.Loose); loggerMock.Setup(lg => lg.Log(It.IsAny(), It.IsAny(), It.IsAny())) .Callback((string s, Category c, Priority p) => Debug.Write(string.Format("**** {0}", s))); 

稍后您可以通过构造函数或属性将loggerMock.Object传递给测试对象,或者配置使用它的dependency injection器。

听起来您正在考虑包装日志记录实现,然后与不同的团队共享。 基于此,这里有一些优点和缺点。

包装的优点

  • 可以从实现中抽象出接口和依赖关系。 这提供了一些防止实现库中的更改的措施。
  • 可以使标准实施更容易,并协调不同项目的实施。

包装的缺点

  • 额外的开发工作。
  • 潜在的额外文档工作(如何使用新库)。
  • 包装代码中的错误比成熟的库更容易出错。 (部署您的错误修复可能会非常头疼!)
  • 开发人员需要学习新的库(即使非常简单)。
  • 有时可能难以包装整个库以避免泄漏实现接口。 这些类型的包装类通常不提供混淆之外的任何其他值。 例如,MyDbCommand类包装了一些其他DbCommand类。

我之前已经包装了部分企业库,我认为它没有增加太多价值。 我觉得你会更好:

  • 记录最佳实践和用法
  • 提供参考实施
  • validation合规性(代码审查等)

这更像是一个主观问题,但IMO将任何应用程序/库特定用法包装到服务模型设计中是一件好事,该服务模型设计具有深思熟虑的接口,因此您可以轻松使用DI,以后如果您需要从EntLib数据切换应用程序块到NHibernate你不需要重新构建你的整个应用程序。

我通常会创建一个“帮助器”或“服务”类,可以静态调用它来包装这些库的常用function。

我不知道直接引用/调用这些风险存在巨大的风险,因为它们肯定是成熟的项目(至少是EntLib和Log4Net),但是使用包装器可以将您与版本更改的混淆等隔离开来。以相当低的成本为您提供更多选择。

我认为最好单独使用包装器,因为这些是您在unit testing运行时不想运行的东西(假设您也进行了unit testing)。

是的,如果现在或在合理的将来能够替换实施是一项要求。

不,否则。

定义应用程序将用于所有日志记录/进取/ …目的的接口是此处的核心工作。 编写包装器只是使编译器强制使用此接口而不是实际实现的一种方法。