跨.NET和Monotouch的代码重用已经以多种方式解决,但大多数技术涉及并行的项目/解决方案集。
我想要这个问题来澄清是否有可能使用单个csproj文件构建 .NET或相同程序集的MonoTouch版本,基于所选平台和配置。
假设如下:
问题:鉴于这些假设,图书馆可以
基于当前的Visual Studio平台和配置?
当前研究
<NoStdLib>true</NoStdLib>
,以及System,System.Core,System.Xml等的不同HintPath
似乎是必要的。答案 0 :(得分:3)
事实证明,MSBuild实际上很可能。 关键点,假设您开始使用为Windows .NET创建的C#项目,您也想为iOS编译,如下所示。 注意:这不适用于MonoDevelop。它仅适用于Visual Studio。这是因为MonoDevelop目前不使用完整的MSBuild兼容的MonoTouch构建系统。
对于iOS平台,将NoStdLib设置为true以避免自动引用mscorlib.dll。还要设置一个目录的路径,该目录包含从Mac上的MonoTouch安装中复制的MonoTouch dll的本地副本:
<PropertyGroup Condition="'$(Platform'=='iOS'">
<NoStdLib>true</NoStdLib>
<iOSLibs>c:\MonoTouch\</iOSLibs>
</PropertyGroup>`
从文件夹中添加对所有引用的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>
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二进制兼容程序集,如magic,,无需使用可移植类库! (这并不意味着PCL没用,它们肯定是,但这里显示的技术更普遍适用。)
更详细的MSBuild知识及其相当大的功能将帮助您进一步简化,例如:
<DefineConstants>...</DefineConstants>
定义编译器常量,以允许代码根据当前解决方案和配置以不同方式执行操作。答案 1 :(得分:1)
从技术上讲,应该可以使用https://github.com/jbevain/cecil之类的工具重写生成的程序集以定位不同的平台,但我认为这不值得付出(巨大的)努力。拆解和重建是另一种(昂贵的)选择。
如果您的问题是关于重新定位第三方提供的程序集,并且这是您唯一的计划,请确保您没有违反任何许可条款。
现在,如果您可以删除一些假设,并使用不同的构建系统(如rake或make),您还可以在构建文件级别实现不使用PCL的代码共享。
希望它有所帮助。