2013-05-08 31 views
5

我正在尝试设置MvvmCross应用程序项目并针对它运行单元测试(即视图模型)。我在OS X上使用Xamarin Studio(v。4.0.4,在撰写本文时为最新版本)。无法加载从Cirrious.MvvmCross.dll引用的MvvmCross程序集:System

MvvmCross应用程序设置为便携式类库。测试程序集被设置为一个简单的Mono/.Net程序集(而非PCL),引用NUnit框架。

当试图执行测试时,它们失败,出现System.TypeLoadException

我已经运行了Mono binding log的测试。下面是输出:

Mono: The following assembly referenced from /Users/jr/dev/rowinginmotion-cross/RowingInMotion.Mobile.BoatApp.Tests/bin/Debug/Cirrious.MvvmCross.dll could not be loaded: Assembly: System (assemblyref_index=3) Version: 2.0.5.0 Public Key: 7cec85d7bea7798e System error: Invalid argument

Mono: Failed to load assembly Cirrious.MvvmCross[0x559960]

Mono: Could not load file or assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or one of its dependencies.

这是测试装置不支持=

回答

5

这个问题被链接到的事实,Xamarin和Mono还没有正确地支持便携式类库 - 相反,他们编译和对本地链接固定程序集取决于您已加载的Mono(Xamarin.Android,Xamarin.iOS等)的版本 - 请参阅http://slodge.blogspot.co.uk/2013/01/almost-portable-binaries.html了解更多信息。在Windows上,您将能够使用BindingRedirect功能解决此问题,但我还没有找到任何方法在Xamarin环境中使用XBuild解决问题(例如,请参阅http://forums.xamarin.com/discussion/3733/playing-with-pcls上的我的PCL和Mac问题)

我目前在完整的.Mac(.Net)项目中加载此代码的唯一方法是使用Xamarin推荐的文件链接方法 - 复制项目文件并专门针对相应目标编译重复项。

希望这种情况很快就会发生变化 - 因为官方PCL支持在未来几天和几周内即将发布。

1

除了@斯图尔特的答案(这是正确的),我想发布第二个解决方法,我发现允许我实现我想要的场景(在Mac OS和Windows上测试PCL组件)。

该解决方法依赖于引入了对通配符包括的支持的Xamarin Studio 4.0.5(或更高版本)。

具体来说,在Windows上编译时,我编译PCL并从测试程序集中为其添加项目引用。在Mac OS上,我编译'PCL'(现在也没有真正的PCL支持),但是我保留它不受测试程序集的影响。相反,我通配符将PCL项目中的所有代码包含到测试程序集中,因此我在OS X上的测试程序集中包含测试代码。

这需要一些MSBuild魔术(类似的技巧用于在Windows和OS之间切换MvvmCross引用X版)。包括这个.targets文件在您的项目的顶部:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Condition=" '$(OS)' == 'Windows_NT'"> 
    <MvvmCrossPlatform>VS2012</MvvmCrossPlatform> 
    <PclSupport>true</PclSupport> 
    </PropertyGroup> 
    <PropertyGroup Condition=" '$(OS)' != 'Windows_NT'"> 
    <MvvmCrossPlatform>XS-iOS-Mac</MvvmCrossPlatform> 
    <PclSupport>false</PclSupport> 
    </PropertyGroup> 
</Project> 

然后在你的单元测试的.csproj:

<ItemGroup Condition=" '$(PclSupport)' == 'false' "> 
    <Compile Include="..\RowingInMotion.Mobile.Backend\**\**.cs">  
     <Link>_Inlined\%(RecursiveDir)%(FileName)%(Extension)</Link> 
    </Compile> 
    </ItemGroup> 

    <Choose> 
    <When Condition=" '$(PclSupport)' == 'true' "> 
     <ItemGroup> 
     <ProjectReference Include="..\RowingInMotion.Mobile.Backend\RowingInMotion.Mobile.Backend.csproj"> 
      <Project>{0B448743-182C-4ADC-8E97-7F9E7EF3A03A}</Project> 
      <Name>RowingInMotion.Mobile.Backend</Name> 
     </ProjectReference> 
     </ItemGroup> 
    </When> 
    </Choose> 

注意,我不得不使用选择构造使ProjectReference有条件的话,似乎只是在其项目组上使用条件不会使Visual Studio和Xamarin Studio加载/忽略项目引用。似乎Xamarin Studio没有正确地扩展%(RecursiveDir)...声明,因此这些文件保留了他们丑陋的文件名(不过,只要它们隐藏在他们的_Inlined文件夹中,我不会在意)。

相关问题