Question

I want to create a PCL for .NET 4.5, Windows 8, Windows Phone 8.1 and Silverlight 5, however I am not able to use ICommand when checking all of these platforms, although all of them should support it according to MSDN.

Steps to reproduce:

  • Create a PCL project with .NET 4.5, Windows 8, and Silverlight 5
  • Create a class that implements ICommand and generate the members
  • Build succeeds

  • Add Windows Phone 8.1 in the project settings

  • Build fails (cannot find System.Windows)
  • If you remove either Silverlight or WP it works, but with both active at the same time it doesn't.

Is this is bug? Or am I missing something?

Was it helpful?

Solution

Unfortunately we weren’t able to support ICommand (and other ViewModel types such as ObservableCollection) in PCLs that target both Silverlight 5 and Windows Phone 8.1. I’d suggest dropping SL5 support from the PCL and supporting that platform via a non-portable library.

OTHER TIPS

I believe the best solution you can accomplish here is to create a shared project and put all of your code inside of it (VS2013.2+ required) and then created a PCL (profile 259) for everything but SL5 and then a SL5 class library (both with shared references to the shared project). This will give you the ability to target all platforms (but unfortunately require two empty assemblies for universal platform support).

@DanielPlaisted any input on whether or not MS will be refactoring very generic types (like ICommand) to less platform specific assemblies/namespaces? (sorry for asking but you seem to have inside knowledge).

While this question is a year old, I ran into a blog post that helps solve this problem: http://dotnetbyexample.blogspot.com/2014/05/writing-behaviors-in-pcl-for-windows.html -- This blog contains a download sample as well, so you can examine its inner workings. The blog works with the IBehavior interface, but the conept is the same.


Basically, the technique is called the "NuGet bait and switch"; you would need to create a NuGet package that contains a PCL library and a platform-specific library (one for each platform).

Let's imagine that your PCL is going to be called "AwesomeMvvm". You would need:

  • AwesomeMvvm (Portable Class Library)
  • AwesomeMvvm.Silverlight
  • AwesomeMvvm.Windows81
  • ...

When you attempt to use the ICommand interface in your portable class library (PCL), you will get an error stating Cannot resolve symbol ICommand. To solve this, simply create an interface making sure it is in the same namespace System.Windows.Input. Your portable class library can now compile!

Now that your portable class library is compiled, create your platform-specific libraries and add a reference to your portable class library to them. Each of these libraries only need one code file that contains the TypeForwardedToAttribute as an assembly-level attribute:

[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Windows.Input.ICommand))]

The final step is to create a single NuGet package containing the portable class library, as well as each platform-specific library. If you did everything correctly, add a reference from your NuGet feed and everything should work just fine. NuGet will prefer the platform-specific libraries whenever it can, each of which rely on the portable class library. The trick is that at runtime it will use the native version of ICommand because you specified to forward your portable class library version to be forwarded to the platform-specific version.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top