【问题标题】:Project reference vs. file links in Mono multi-target projectsMono 多目标项目中的项目参考与文件链接
【发布时间】:2012-09-10 11:59:40
【问题描述】:

我已经看到了一些关于这个问题的讨论,但我还没有看到明确的答案,当然不是 MonoTouch / Mono for Android。

我正在开发一个基于 Xamarin 的多目标解决方案,当然我有很多通用代码。理想情况下,此代码将驻留在“通用”标准 .NET 类库项目(或项目)中。当我在特定于平台的项目中引用此项目时,我确实收到警告“无法引用项目'Common'。引用的项目针对不同的框架系列 (.NETFramework)”,但解决方案仍然编译成功。

本质上,我问的是当我的通用代码处理多个目标时是否必须使用文件链接方法。更详细地说,我的问题是:

  1. 当我的“通用”项目仅引用 Mono* 目标支持的程序集时,上述方法是否有效?
  2. 如果上面的答案是肯定的:假设我在我的“通用”项目中引用了第 3 方 .NET 库(以 DLL 的形式,而不是项目),并且该库确实具有针对不同目标的不同程序集(但它没有引用 Mono* 不支持的程序集),我仍然可以引用 Windows 版本的程序集并摆脱它吗?

【问题讨论】:

    标签: .net mono xamarin.ios xamarin.android


    【解决方案1】:

    有一种叫做可移植类库的东西已经出现了一段时间。从 Visual Studio 2012(2012-09-12 发布)开始,它现在是 Visual Studio 的一等公民,因此您可以在 Windows 8、Windows Phone、Silverlight、Windows

    我希望 MonoDevelop 遵循这条路线,以便即使使用 Mono for Android 和 MonoTouch 也可以共享可移植库。

    同时,您应该为每个平台创建一个项目,即使 链接 到相同的源文件。我发现这是最好的解决方案:

    这样命名的项目文件

    MyCompany.MyProduct.MyModule.Ios.csproj
    MyCompany.MyProduct.MyModule.Android.csproj
    MyCompany.MyProduct.MyModule.WinPhone.csproj
    

    所有项目中的命名空间只有 MyCompany.MyProduct.MyModule。

    您将项目中的相同 cs 文件链接到“共享”文件夹。

    如果您需要在 Ios 版本中公开一些额外的类,您只需将该文件添加到 Ios 项目(未链接)并将 .Ios 添加到命名空间,因为您希望跨平台命名空间不会被平台弄乱具体的东西。

    这是一个不会破坏 Windows 路径长度问题的文件夹结构:

    /MyCompany/MyProduct/
    

    这里放置所有目标平台的解决方案文件,命名如下:

    MyCompany.MyProduct.Ios.sln
    MyCompany.MyProduct.Wpf.sln
    ...
    

    每个程序集的文件夹:

    /MyCompany/MyProduct/MyModule/
    

    这里你放了一个“Shared”文件夹,每个平台一个文件夹,所以:

    /MyCompany/MyProduct/MyModule/Shared/
    

    仅跨平台代码(从每个项目文件链接到)!!!

    /MyCompany/MyProduct/MyModule/Android/
    /MyCompany/MyProduct/MyModule/Ios/
    /MyCompany/MyProduct/MyModule/WinPhone/
    /MyCompany/MyProduct/MyModule/Wpf/
    /MyCompany/MyProduct/MyModule/Mac/
    ...
    

    这是您放置模块每个平台的项目文件的位置,也是放置在特定平台上实现模块所需的任何平台特定 cs 文件的位置。

    这对我们很有效。

    【讨论】:

      【解决方案2】:

      MonoTouch 与 Android 的 Mono 类似,提供常规(桌面).NET 框架的子集。

      这个子集实际上是为 Silverlight(我们当时称为 FX 2.1)提供的基类库 (BCL) 的超集。

      如果您的二进制文件引用 MonoTouch(或 Android 的 Mono)中不存在的类型、方法(任何元数据),您将遇到 12 问题)。

      使用 MonoTouch,您会在为设备构建时发现此类问题,因为使用了 AOT(提前)编译。 IOW 缺少的符号将在构建时找到。请注意,JIT 用于 iOS 模拟器,因此在运行时需要它们之前,不会找到丢失的符号。

      Mono for Android 正在使用 JIT(在设备和模拟器上),因此在运行时更可能找到任何丢失的元数据 - 即托管链接器也会找到丢失的成员并且不会如果无法解析符号,则能够创建新的、更小的程序集。

      所以除非您使用产品随附的 SDK 程序集 (BCL) 重新编译代码,否则该方法无效(因为 100% 安全)。

      【讨论】:

      • 谢谢@poupou,但是.. 1. 正如我所说,你可以假设我只在我的公共项目中使用 BCL 子集。 2. 是否可以有一个通用的“BCL 类库”项目供所有目标使用? 3. 在“onlt BCL-safe”假设下,我的第二个问题呢?
      • 1. 编译器本身可能使用早期框架中不可用的符号(例如 Type new == 运算符)在早期框架中 - 这打破了您的假设. 2.最好的方法是针对最小的子集构建(例如针对 MonoTouch SDK 程序集构建公共代码)并将其用于较新的框架。 3. 除非您重新编译代码,否则没有安全 的方法,即您无法知道预编译的第 3 方使用的是什么编译器。它可能有效,也可能无效。
      猜你喜欢
      • 1970-01-01
      • 2011-01-24
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      相关资源
      最近更新 更多