.net - 从单个 .csproj 构建(非 PCL)Monotouch 或 .net dll

标签 .net msbuild xamarin.ios reusability mono.cecil

跨 .NET 和 Monotouch 的代码重用已通过多种方式解决,但大多数技术都涉及平行的项目/解决方案集。

我想通过这个问题澄清是否可以使用单个 csproj 文件构建同一程序集的 .NET 或 MonoTouch 版本,基于所选平台和配置。

假设如下:

  1. 构建机器运行 Windows。
  2. 可以使用 Visual Studio 和 MSBuild。
  3. 该方法不需要在 MonoDevelop 上运行,因为 MonoDevelop 当前没有为 MonoTouch 打开 XBuild/MSBuild。
  4. 来自有效 MonoTouch 安装的 MonoTouch 二进制文件可用。
  5. 只需要构建一个库,而不是一个完整的应用程序。这个库:
    1. 不包含任何 .xib 或 plist。
    2. 是否使用特定于平台的代码,这些代码将被有条件地编译。
    3. 是否(必要)引用特定于平台的程序集,这些程序集需要由 .csproj 文件处理。

问题:鉴于这些假设,图书馆可以

  1. 为 Windows .NET 或
  2. 编译
  3. 在将二进制文件复制到 Mac 后,为 MonoTouch 应用解决方案直接引用而编译。

基于当前的 Visual Studio 平台和配置?

当前研究

  1. MonoTouch 解决方案可以使用在 Windows 上编译的可移植库这一事实给了我们希望这是可能的。
  2. 使用<NoStdLib>true</NoStdLib>在为 MonoTouch 构建时的 .csproj 中,以及不同的 HintPath用于 System、System.Core、System.Xml 等的 s 似乎是必要的。
  3. 不确定在为 MonoTouch 构建时如何引用正确版本的 mscorlib。

最佳答案

事实证明,使用 MSBuild 这实际上是很有可能的。 假设您从为 Windows .NET 创建的 C# 项目开始,您还想为 iOS 编译,关键点如下。 注意:这不适用于 MonoDevelop。它仅适用于 Visual Studio。这是因为 MonoDevelop 目前没有为 MonoTouch 使用成熟的 MSBuild 兼容构建系统。

  1. 为 iOS 创建一个名为 iOS 的新解决方案和项目平台。这用于为 MonoTouch 编译项目。您可以随意命名此名称,但请在下文中始终使用该名称。
  2. 对于 iOS 平台,将 NoStdLib 设置为 true 以避免自动引用 mscorlib.dll。还要将路径设置为包含 MonoTouch dll 的本地副本的目录,从 Mac 上的 MonoTouch 安装复制:

    <PropertyGroup Condition="'$(Platform'=='iOS'">
      <NoStdLib>true</NoStdLib>
      <iOSLibs>c:\MonoTouch\</iOSLibs>
    </PropertyGroup>`
    
  3. 添加对文件夹中所有引用的 MonoTouch 程序集的本地副本的引用:

    <ItemGroup Condition="'$(Platform'=='iOS'">
      <Reference Include="mscorlib">
        <HintPath>$(iOSLibs)\mscorlib.dll</HintPath>
      </Reference>    
      <Reference Include="System">
        <HintPath>$(iOSLibs)\System.dll</HintPath>
      </Reference>    
      <Reference Include="System.Core">
        <HintPath>$(iOSLibs)\System.Core.dll</HintPath>
      </Reference>    
      <Reference Include="System.Xml"> 
        <HintPath>$(iOSLibs)\System.Xml.dll</HintPath>
      </Reference>
      <Reference Include="System.Xml.Linq"> 
        <HintPath>$(iOSLibs)\System.Xml.Linq.dll</HintPath>
      </Reference>
      <Reference Include="monotouch">
        <HintPath>$(iOSLibs)\monotouch.dll</HintPath>
      </Reference>    
    </ItemGroup>
    
  4. Visual Studio 自动添加一个引用所有 .NET 程序集的 ItemGroup。由于我们已指示 Visual Studio/MSBuild 在为 iOS 构建时从 iOSLibs 文件夹中获取这些,因此我们应该有条件地禁用默认程序集。这会阻止 VS 提示重复的程序集引用。更改 ItemGroup 的第一行并按如下方式添加条件。 (注意:程序集列表将根据您的项目当前引用的内容而有所不同。)

    <ItemGroup Condition=" '$(Platform)' != 'iOS' ">
      <Reference Include="System" />
      <Reference Include="System.Core" />
      <Reference Include="System.Drawing" />
      <Reference Include="System.Windows.Forms" />
      <Reference Include="System.Xml.Linq" />
      <Reference Include="System.Data.DataSetExtensions" />
      <Reference Include="Microsoft.CSharp" />
      <Reference Include="System.Data" />
      <Reference Include="System.Xml" />
    </ItemGroup>
    

现在您可以开始了。为解决方案中的所有项目完成此操作后,您可以从“解决方案”下拉列表中选择 iOS 并像魔术一样构建与 MonoTouch 二进制兼容的程序集,无需使用可移植类库! (这并不意味着 PCL 没有用,它们肯定有用,但这里展示的技术更普遍适用。)

更详细地了解 MSBuild 及其强大的功能将帮助您进一步简化,例如:

  1. 将上述大部分内容移动到一个通用的 MSBuild 文件中,您可以从所有项目文件中引用该文件以消除重复。
  2. 使用 <DefineConstants>...</DefineConstants> 定义编译器常量允许您的代码根据当前的解决方案和配置以不同的方式执行操作。

关于.net - 从单个 .csproj 构建(非 PCL)Monotouch 或 .net dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14759351/

相关文章:

.net - 访问 Form 上的成员可能会导致运行时异常,因为它是 marshal-by-reference 类的字段

.net - 引用不属于 .NET Standard 的程序集

c# - FtpWebRequest 下载文件

command-line - 为什么 MSBuild 只能在开发人员命令提示符下正常工作?

asp.net-mvc - 基于条件编译符号启用 MVCBuildViews

当 maxcpucount 大于 1 时,MSBUILD 失败并显示 "The process cannot access the file xxxxx because it is being used by another process."

uinavigationcontroller - 通过子类化定义自定义 UINavigationBar 会删除导航项

c# - ASP.NET 站点 - 在特定时间触发一些代码

c# - Xamarin iOS - MVVMCross : Unable to connect button in custom cell with command in ViewModel

xamarin.ios - 为 Visual Studio 2013 Express 安装 Xamarin