2013-05-08 97 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文件夾中,我不會在意)。