Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use a Portable Class Library that references System.Net in MonoDroid?

Following from How can I build a targetting pack for Portable Class Libraries? and the advice in http://jpobst.blogspot.com/2012/04/mono-for-android-portable-libraries-in.html I've managed to build some monodroid example programs which use Portable Class Libraries.

However, if any of my input PCLs reference the System.Net assembly, then monodroid fails to package my apk - because it complains about File Not Found for System.Net.dll.

As I understand it (from http://docs.xamarin.com/android/about/assemblies), MonoDroid bundles all the System.Net functionality inside System.dll.

Is there any way I can get MonoDroid to use these PCLs which reference System.Net?

  • Is there any way I can get the monodroid packager to understand this System.net-> System redirection?
  • Or is there some pre-package step I could run that would "correct" the referencing just for monodroid?
  • Or any other suggestions?

Update with technical info:

The packaging process is currently failing at the level of:

"C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj" (SignAndroidPackage target) (1) ->
(_ResolveAssemblies target) -> 
  C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error : Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'System.Net, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'. Perhaps it doesn't exist in the Mono for Android profile? [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]
C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error : File name: 'System.Net.dll' [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]
C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error :    at Monodroid.Tuner.MonoDroidResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters) [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]
C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error :    at Xamarin.Android.Tasks.ResolveAssemblies.AddAssemblyReferences(List`1 assemblies, AssemblyDefinition assembly) [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]
C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error :    at Xamarin.Android.Tasks.ResolveAssemblies.AddAssemblyReferences(List`1 assemblies, AssemblyDefinition assembly) [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]
C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error :    at Xamarin.Android.Tasks.ResolveAssemblies.AddAssemblyReferences(List`1 assemblies, AssemblyDefinition assembly) [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]
C:\Program Files (x86)\MSBuild\Novell\Novell.MonoDroid.Common.targets(441,2): error :    at Xamarin.Android.Tasks.ResolveAssemblies.Execute() [C:\Projects\Misc\MVVMCROSS\Sample - Tutorial\Tutorial\Tutorial.UI.Droid\Tutorial.UI.Droid.csproj]

This is occurring within the MSBuild task:

<!-- Find all the assemblies this app requires -->
<ResolveAssemblies
    Assemblies="$(ProjectDir)$(OutDir)$(TargetFileName);@(ReferencePath)"
    I18nAssemblies="$(MandroidI18n)"
    LinkMode="$(AndroidLinkMode)"
    ReferenceAssembliesDirectory="$(TargetFrameworkDirectory)">
        <Output TaskParameter="ResolvedAssemblies" ItemName="ResolvedAssemblies" />
  <Output TaskParameter="ResolvedUserAssemblies" ItemName="ResolvedUserAssemblies" />
  <Output TaskParameter="ResolvedFrameworkAssemblies" ItemName="ResolvedFrameworkAssemblies" />
  <Output TaskParameter="ResolvedSymbols" ItemName="ResolvedSymbols" />
  </ResolveAssemblies>

imported from:

  <UsingTask TaskName="Xamarin.Android.Tasks.ResolveAssemblies" AssemblyFile="Novell.MonoDroid.Build.Tasks.dll" />
like image 579
Stuart Avatar asked Apr 28 '12 07:04

Stuart


1 Answers

A possible solution (assuming MonoDroid supports type forwarding) is to have a System.Net.dll assembly which type forwards the relevant types to System.dll.

In the full .NET Framework, I believe those System.Net types are in System.dll, and if you look in System.Net.dll on .NET 4.0.3 or 4.5, you will see TypeForwardedToAttributes for those types, which allow those type references to System.Net.dll in a portable library to be redirected to System.dll. Jeremy Likness's blog post series on Understanding Portable Libraries goes into some detail about how this all works.

The references in a portable library refer to the full strong name of System.Net.dll. So you couldn't produce a correctly signed assembly with those type forwards yourself, since you don't have the private key. However, MonoDroid may handle strong names or signature validation differently. So you might be able to produce a System.Net.dll with the type forwards that MonoDroid would accept, and package it with your MonoDroid application.

like image 165
Daniel Plaisted Avatar answered Oct 14 '22 05:10

Daniel Plaisted