I need to add and/or modify profiles to allow more classes and members to be shared in PCL (many of them are built-in in framework, such as Thread.Sleep). What's the best way to do this? Are there any tools to help that?
PS: I'm not seeking an anwser to tell me NO or STOP. I want to have compile-once DLLs that may be shared in different environment. No per-platform binary, no recompile, no ifdef.
Following is what I got so far:
Requirement:
- Target environements: Silverlight 5 and .NET Framework 4.5.
- Purpose of PCLs: shared infrastructure by RIA client and ASP.NET server (without WCF)
- What's lacking in default profiles: XPath, Thread methods, DynamicMethod/ILGenerator
PCL profiles: under Reference Assemblies\Microsoft\Framework.NETPortable:
- All assemblies are stubs, with "Retargetable" attribute set.
- All assemblies have flags = 0x171: 0x001 is signed, 0x100 is retargetable, and 0x070 is undefined in AssemblyNameFlags (appears to have no effect)
- All references between assemblies are with "Retargetable" attribute as well.
- All assemblies with Silverlight support are versioned 2.0.5.0.
- Built PCL binaries contain two references for each of referred assemblies (ex: mscorlib 2.0.5.0 retargetable + mscorlib 4.0)
Customization attempt #1
- Profile: Silverlight 5 + .NET Framework 4.5 (profile 24)
- Copy SL5 mscorlib.dll to profile 24
- Mark SL5 mscorlib.dll as retargetable (change to delay signed)
- ReSharper: failed to resolve all extension methods, error in generic type/value match
- Build: success, Run: success
Customization attempt #2
- Profile: Silverlight 5 + .NET Framework 4.5 (profile 24)
- Copy all SL5 DLLs to profile 24
- Mark all SL5 DLLs as retargetable (change to delay signed)
- Mark all references between SL5 DLLs' as retargetable
- ReSharper: failed to resolve all extension methods, error in generic type/value match
- Build: success, Run: success
Customization attempt #3
- Profile: Silverlight 4 + .NET Framework 4.0.3 (profile 18)
- Copy SL4 mscorlib.dll to profile 18
- Mark SL4 mscorlib.dll as retargetable (change to delay signed)
- ReSharper: success
- Build: success, Run: success
Customization attempt #4
- Profile: Silverlight 4 + .NET Framework 4.0.3 (profile 18)
- Copy all SL4 DLLs to profile 18
- Set .NET runtime version of all SL4 DLLs to v4 (original DLLs have that, unknown of effects)
- Mark all SL4 DLLs as retargetable (change to delay signed)
- Mark all references between SL4 DLLs' as retargetable
- ReSharper: success
- Build: success, Run: success
Customization attempt #5 inherit #4
- Profile: Silverlight 4 + .NET Framework 4.0.3 (profile 18)
- Add SL4's System.Numerics (included in other SL profiles) to RedistList\FrameworkList.xml
- Add SL4's System.Xml.XPath (not included in any SL profiles) to RedistList\FrameworkList.xml
- Result: unable to resolve System.Numerics and System.Xml.XPath from default PCL references
- Fixes: reference both DLLs manually - unable to force them to be retargetable, though VS wouldn't compile with non-retargetable System.Numerics or System.Xml.XPath due to the noted problem below
Notes:
- Compile error: "... defined in an assembly that is not referenced, You must add a reference to assembly". Happens after all assemblies are made retargetable but one of references between them is not changed to "retargetable"
It works to a certain degree, but quite troublesome to customize existing referenced DLLs or add new ones, nor can one easily validate PCL code after overriding referenced DLLs (if possible at all).
NO. STOP.
OK, since that's not what you want to hear, continue at your own risk. :) This certainly isn't supported, and IANAL so I don't know if it would be allowed by the license agreement either.
It sounds like the main problem you have with your existing solutions is that you can't pick individual APIs to add to the portable profile. To do that, you could use ildasm on the existing reference assemblies, then add in the APIs you want (probably by copying them from the results of running ildasm on another reference assembly), and then use ilasm to create your own versions of the reference assemblies with those additional APIs.
You'll need to delay sign and/or disable strong name key verification for the keys for the assemblies you modify this way.
Another option is to use type-forwarding, as described in my answer here. In that case you would end up with your main code being shareable as is, with a dependency on a DLL that would be different for each platform.