如何管理同一个dll的多个目标平台?

时间:2013-07-22 21:56:21

标签: .net visual-studio silverlight tfs projects-and-solutions

我们在TFS中有一个专门用于通用代码的TeamProject,例如一般扩展方法,实用程序类,可以与我们公司的每个团队共享的东西。它在某种程度上像.Net框架本身的扩展。

目前有许多按区域分隔的项目,因此当团队需要部分功能时,他们不必每次都用它们拖动一堆依赖项。这些项目的命名约定遵循格式[OurCompany].Framework.[Equivalent .Net Namespace]

以下是我们在解决方案中使用的dll的几个示例:

  • Mobiltec.Framework.dll
  • Mobiltec.Framework.Web.dll
  • Mobiltec.Framework.Data.dll
  • ...

当我们尝试为不同平台制作相同的扩展时,会出现问题。例如,有一个针对Silverlight的Mobiltec.Framework.dll,以及一个针对WindowsMo​​bile平台的Mobiltec.Framework.dll。当解决方案构建在构建服务器上时,每个输出都会转到同一个文件夹,并且只保留最后一个具有相同名称的内置DLL(之前构建的dll会被覆盖)。这显然会导致每个依赖于覆盖文件的下一个项目发生错误。

我认为不在dll名称上指定平台是一个很好的做法,似乎是第三方库甚至.Net框架dll的标准。 Nuget包似乎也鼓励(log4net浮出水面),其中不同的版本由文件夹分隔,这些文件夹指示它们在哪个平台/ .net版本中工作,而dll名称本身是相同的。

我是否应该为每个平台和/或此框架的每个.Net版本创建不同的解决方案?我们目前有两个解决方案,因为Visual Studio 2012不支持智能设备项目。有一个Framework.Legacy.sln文件,其中包含所有以Windows Mobile SDK为目标的项目,另一个包含所有其他项目(桌面,Silverlight等)。

理想情况下,我真的希望在同一个解决方案中共享尽可能多的项目,因为重构任务更容易(通过链接的.cs文件在平台之间共享某些功能)。

由于我刚刚在TFS上创建了这个项目的构建(因此只是意识到了这个问题),我在不同的解决方案中分离了我们框架的Silverlight版本,并将“特定于解决方案的构建输出”选项设置为“真正的”构建定义。我们现在有3个解决方案(一个用于WindowsMo​​bile,另一个用于'普通.Net4',另一个用于Silverlight 5)。目前,一切似乎按预期工作,但我觉得我们正在失去重构潜力,并想知道是否有更好的解决方法,考虑到我们可以在附近添加另一个版本(例如用于Windows RT)将来

我想知道的是我们应该如何正确地管理它,以便它可以与TFS构建系统一起使用,同时易于维护?我确信还有其他人必须处理同样的问题。你是怎么处理的?

1 个答案:

答案 0 :(得分:2)

您有一个独特的情况,您希望定位许多主流产品,但也是传统产品。我看到你有两个主要选择。

便携式类库(PCL)

理想情况下,您需要创建Portable Class Library(PCL)。 PCL允许您使用一个项目定位许多不同的平台。因此,在您的示例中,您只需要一个Mobiltec.Framework项目,它可以在multiple platforms中使用。对于您要支持的大多数平台,这仍然是一个选项。他们support what you need提供的PCL很棒。 PCL不允许一切,但你可以绕过这些限制与其他PCL,建立自己的对象表示,或通过依赖注入。

针对不同平台的多个项目

使用此选项,您可以为要支持的每个平台向解决方案添加一个csproj(您可以通过编辑项目属性来避免程序集的构建位置问题。在构建选项卡上,您可以指定位置已组装。将此设置为特定于平台)。在您的示例中,您将拥有一个针对Silverlight的Mobiltec.Framework,一个针对.Net3.5的平台,一个针对Windows Phone的平台,等等。将每个项目文件命名为不同的内容(例如:Mobiltec.Framework,Mobiltec.Framework.Silverlight等。)但保持程序集名称相同(项目属性的应用程序选项卡)。

每个项目都会adding them as links使用相同的文件。这允许您在一个文件中进行更改,但对每个项目都有效。这些项目为您提供了所针对的平台的完全支持,但并非所有平台都相同。您将发现自己必须在代码文件中使用#if语句

public void Foo()
{
#if SILVERLIGHT
        // do something
#else
        // do something else
#endif
}

这两种方法都有很大的好处和很大的缺点。理想情况下,您可以拥有适用于所有较新平台的PCL库和一个针对Windows Mobile的项目。如果你无法做到这一点(你的新项目需要不可用的东西),那么第二种方法仍然是一个很好的方法。在任何一种情况下都不需要代码重复。