正如其他人所暗示的那样,您永远不想在多个项目中直接包含相同的代码文件。这几乎不是一个好主意,它总是会导致代码混乱。如果您有想要在两个不同项目之间共享的公共代码,那么您需要创建第三个项目(类库),其中将包含公共代码,然后其他两个项目将只引用类库。如果您可以在同一个解决方案中拥有所有三个项目,那么您可以使用项目引用,这是最好的。但是,如果您不能这样做,您仍然可以直接引用该类库项目输出的 DLL 文件。
其次,如果你真的想避免意大利面条式代码,你应该认真研究依赖注入(DI)。我和其他人提出这个建议的原因是,即使您将公共代码移动到类库中以便可以由多个项目共享,您仍然会遇到您的类库充当“黑盒”的问题“它神奇地为你找出一切,并在每种情况下采取适当的行动。从表面上看,这听起来像是开发人员应该努力争取的一件好事,但实际上,从长远来看,这会导致糟糕的代码。
例如,当您想在 100 个不同的项目中使用相同的日志记录类库并且它们都需要以稍微不同的方式进行日志记录时会发生什么。现在,您的类库必须神奇地检测所有这些不同的情况并处理它们。例如,某些项目可能需要将日志保存到不同的文件名。有些可能需要将日志存储到 Windows 事件日志或数据库中。有些人可能需要在记录错误时自动通过电子邮件发送通知。等等你可以想象,随着项目的增加和需求的增长,日志类库将需要变得越来越复杂和混乱,这将不可避免地导致更多的错误。
另一方面,DI 解决了所有这些问题,如果您坚持该方法,它将从本质上迫使您编写可重用的代码。简单来说,它只是意味着一个类的所有依赖项都应该被注入(通过参数传递)到它里面。换句话说,如果 Logger 类需要事件日志或数据库连接,它不应该自己创建或伸出手来查找这些东西。相反,它应该只要求将这些依赖项传递给它(通常在构造函数中)。您使用 DI 的示例可能如下所示:
Public Interface ILogFilePathFinder
Function GetPath() As String
End Interface
Public Class LogFilePathFinder
Implements ILogFilePathFinder
Public Sub New(isOemVersion As Boolean)
_isOemVersion = isOemVersion
End Sub
Private _isOemVersion As Boolean
Function GetPath() As String Implements ILogFilePathFinder.GetPath
If _isOemVersion Then
Return "C:\TestOem.log"
Else
Return "C:\Test.log"
End If
End Function
End Class
Public Interface ILogger
Sub WriteLog(ByVal text As String)
End Interface
Public Class FileLogger
Implements ILogger
Public Sub New(pathFinder As ILogFilePathFinder)
_pathFinder = pathFinder
End Sub
_pathFinder As ILogFilePathFinder
Public Sub WriteLog(text As String) Implements ILogger.WriteLog
Dim path As String = _pathFinder.GetPath()
' Write text to file ...
End Sub
End Class
如您所见,它需要一些额外的工作,但是当您像这样设计代码时,您将永远不会后悔。您会注意到记录器类请求路径查找器作为依赖项。路径查找器反过来请求 OEM 设置作为依赖项。因此,要使用它,您需要执行以下操作:
Dim pathFinder As ILogFilePathFinder = New FileLogPathFinder(_OemSettings.IsOemVersion) ' Note, don't use a global to store the settings, always ask for them to be injected
Dim logger As ILogger = New FileLogger(pathFinder)
logger.WriteLog("test")
现在,您可以在任何情况下轻松重用所有这些代码。例如,如果您有不同的项目需要使用不同的日志文件路径,他们仍然可以使用 commonFileLogger
类,他们只需要各自实现自己的版本,ILogFilePathFinder
然后将自定义路径查找器注入 common FileLogger
. 希望你能看到这样做是如何非常有用和灵活的。