无法加载从Cirrious.MvvmCross.dll引用的MvvmCross程序集:System

时间:2013-05-08 13:42:57

标签: xamarin mvvmcross portable-class-library

我正在尝试设置一个MvvmCross应用程序项目并对其运行单元测试(即其中的视图模型)。我在OS X上使用Xamarin Studio(v.4.0.4,在撰写本文时最新)。

MvvmCross App被设置为便携式类库。测试程序集设置为引用NUnit框架的普通Mono / .Net程序集(不是PCL)。

尝试执行测试时,它们会失败并显示System.TypeLoadException

我已经使用Mono binding log运行了测试。这是输出:

  

Mono:引用以下程序集   /Users/jr/dev/rowinginmotion-cross/RowingInMotion.Mobile.BoatApp.Tests/bin/Debug/Cirrious.MvvmCross.dll   无法加载:        汇编:系统(assemblyref_index = 3)        版本:2.0.5.0        公钥:7cec85d7bea7798e系统错误:参数无效

     

Mono:无法加载程序集Cirrious.MvvmCross [0x559960]

     

Mono:无法加载文件或程序集'System,Version = 2.0.5.0,   Culture = neutral,PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'或   其中一个依赖。

不支持此测试设置=

2 个答案:

答案 0 :(得分:5)

这个问题与Xamarin和Mono尚未正确支持可移植类库这一事实相关 - 而是根据Mono的版本(Xamarin.Android,Xamarin.iOS等)编译和链接本地固定程序集。您已加载 - 请参阅http://slodge.blogspot.co.uk/2013/01/almost-portable-binaries.html以获取更多信息。

在Windows上,您可以使用BindingRedirect功能解决此问题,但我还没有找到任何方法来解决在Xamarin环境中使用XBuild的问题(例如,请参阅我的PCL和Mac问题在http://forums.xamarin.com/discussion/3733/playing-with-pcls

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

希望这种情况很快就会发生变化 - 因为官方的PCL支持将在未来几天和几周内以alpha形式提供。

答案 1 :(得分:1)

除了@Stuart的答案(这是正确的),我想发布第二个解决方法,我发现允许我实现我想要的场景(在Mac OS和Windows上可测试PCL程序集)。

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

具体来说,在Windows上编译时,我编译PCL并从测试程序集中添加项目引用。在Mac OS上,我编译'PCL'(现在还没有真正的PCL支持),但是我从测试程序集中保持不变。相反,我的通配符包括从PCL项目到测试程序集的所有代码,所以我在OS X上的测试程序集中有测试+代码。

这需要一些MSBuild魔法(用于在Windows和OS X版本之间切换MvvmCross引用的类似技巧)。在项目顶部包含此.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>

请注意,我必须使用Choose构造使ProjectReference成为条件,似乎只是在其项组上使用Condition不会使Visual Studio和Xamarin Studio加载/忽略项目引用。似乎Xamarin Studio没有正确扩展%(RecursiveDir)...语句,因此文件保留了丑陋的文件名(只要它们隐藏在_Inlined文件夹中,我就不在乎。)