Search code examples
c#.netportable-class-library

How to use TypeForwardedTo in Portable Class Libraries?


I'm trying to build a Portable Class Library which uses implementations from the platform when available. For example, Lazy<T> is available on .NET 4.5, Windows Store Apps, Windows Phone 8, BUT it's not available on Windows Phone 7, Silverlight 4. When my PCL is loaded on one of the platforms that has a Lazy<T> implementation, I want to use the platform's implementation. When it's not available on the platform, I want to use my own implementation. It seems to be possible because the Microsoft BCL is doing it, but I haven't figured out how to implement it.

I've read that by using the TypeForwardedToAttribute, you can redirect the PCL to use the implementation from the platform. I'm not quite sure how to configure my Visual Studio Projects to achieve this result. If CoreLib is my library, and ShimLib contains my implementation of Lazy<T>. Where do I add the TypeForwardedToAttribute? The attribute requires an actual Type reference typeof(System.Lazy<>), which doesn't work when Windows Phone 7 is targeted in the PCL. If I remove Windows Phone 7, then I can't add a reference from CoreLib to ShimLib because ShimLib doesn't support all the platforms that CoreLib does. How do I handle this?

Yes, I know Lazy<T> is super easy to implement, but it's just an example, and my actual situation applies to many more classes that are less trivial to implement.


Solution

  • The way Microsoft.Bcl does this by shipping two assemblies with the same identity; one with the type itself, and one with the type forward. You reference the one with the type when targeting platforms that don't support Lazy (include portable library combinations that include one of these platforms). And reference the one with the type-forward when targeting platforms with Lazy, this enables to consume libraries built against the older platforms.

    Make note, Microsoft.Bcl has a little advantage that you don't have. We ship an assembly that has the same identity as one that is already in later versions, which means that when a Windows Phone 7 app runs on Windows Phone 8, they get the version that's built in, not the one in the shim library. You are unable to mimic that, but that's probably something you can live with in your situation.