Configure .NET Portable Class Class Library Profiles?

I need to add and / or modify profiles in order to provide more classes and members for sharing in PCL (many of them are built into the framework, for example Thread.Sleep). What is the best way to do this? Are there any tools for this?



PS: I'm not looking for someone to tell me NO or STOP. I want to have compiled DLLs that can be used in different environments. No for each platform, no recompilation, no ifdef.


Here is what I got so far:

Requirements:

  • Target: Silverlight 5 and .NET Framework 4.5.
  • PCL Purpose: Common Infrastructure Using RIA Client and ASP.NET Server (Without WCF)
  • What is missing in default profiles: XPath, Thread methods, DynamicMethod / ILGenerator

PCL profiles: in the reference builds \ Microsoft \ Framework.NETPortable:

  • All assemblies are stubs with a set of retargetable attributes.
  • All assemblies have flags = 0x171: 0x001 is signed, 0x100 is reconfigurable, and 0x070 is undefined in AssemblyNameFlags (it seems to have no effect)
  • All links between assemblies also have the "Retargetable" attribute.
  • All assemblies supporting Silverlight version 2.0.5.0.
  • The embedded PCL binaries contain two links for each of the listed assemblies (for example: mscorlib 2.0.5.0 retargetable + mscorlib 4.0)

Setup Error # 1

  • Profile: Silverlight 5 + .NET Framework 4.5 (Profile 24)
  • Copy SL5 mscorlib.dll to profile 24
  • Mark SL5 mscorlib.dll as redirectable (change to signature delay)
  • ReSharper: failed to resolve all extension methods, error in standard match type / value
  • Build: Success, Launch: Success

Setup Error # 2

  • Profile: Silverlight 5 + .NET Framework 4.5 (Profile 24)
  • Copy all SL5 DLLs to profile 24
  • Mark all SL5 DLLs as configurable (change to signing delay)
  • Mark all links between SL5 DLLs as redirected
  • ReSharper: failed to resolve all extension methods, error in standard match type / value
  • Build: Success, Launch: Success

Attempt setting # 3

  • Profile: Silverlight 4 + .NET Framework 4.0.3 (Profile 18)
  • Copy SL4 mscorlib.dll to profile 18
  • Mark SL4 mscorlib.dll as redirectable (change to signature delay)
  • ReSharper: success
  • Build: Success, Launch: Success

Attempt setting # 4

  • Profile: Silverlight 4 + .NET Framework 4.0.3 (Profile 18)
  • Copy all SL4 DLLs to profile 18
  • Install the .NET version in all versions of SL4 DLL to v4 (source DLLs have unknown effects)
  • Mark all SL4 DLLs as reconfigurable (delay change signed)
  • Mark all links between SL4 DLLs as redirected
  • ReSharper: success
  • Build: Success, Launch: Success

Attempt to configure # 5 inherit # 4

  • Profile: Silverlight 4 + .NET Framework 4.0.3 (Profile 18)
  • Add SL4 System.Numerics (included in other SL profiles) to RedistList \ FrameworkList.xml
  • Add SL4 System.Xml.XPath (not included in any SL profiles) to RedistList \ FrameworkList.xml
  • Result: It is not possible to resolve System.Numerics and System.Xml.XPath from the default links for PCL.
  • Corrections: refer to both DLLs manually - you cannot force them to reconfigure, although VS will not compile with non-intercepting System.Numerics or System.Xml.XPath due to the noted problem below

Notes:

  • Compilation error: "... defined in an assembly that is not referenced, you must add a reference to the assembly." It happens that all assemblies are made reconfigurable, but one of the links between them does not change to “redirected”.

This works to some extent, but it’s rather difficult to customize existing DLLs or add new ones, and it also cannot easily verify PCL code after overriding DLLs (if possible at all).

+7
source share
2 answers

Since you do not accept NO or STOP as an answer, let me try to explain why this is a bad idea. Short answer: if the PCL does not expose the API, this is usually because it will not work.

First of all, PCL does not have its own set of APIs. PCL simply provides the intersection of the APIs between a given set of platforms for which you want to target. Now there are times when crossing the API level will give more APIs than what the PCL provides. There are some tips why this might be so.

  • API not available on all platforms
  • The API is available, but actually does not work.
  • API defined in different assemblies

The first should be obvious. PCL itself is not a real platform, but only reveals what is there. Therefore, we cannot provide you with APIs that do not actually exist on all platforms that you are targeting. In the end, we set the intersection.

The second sounds a little strange, but actually it happens. Take, for example, the IO file on Windows Phone 7. Although the file class is technically available on Windows Phone, it is documented as

This type is present to support the .NET Compact Framework in Silverlight for Windows Phone, and is not intended to be used in your application code.

You can say "what do I need?" and just try, but then you will find out that the security model on the phone will not allow you to access the files you are looking for. Therefore, exposing this API to the PCL would not help. In fact, our team believes that this will actually hurt you, because it will lead you to an unbearable path.

The third question about the API, implemented in different assemblies, is a bit more in demand. To understand why this is a problem, you need to think about how the CLR handles the API as a whole. The CLR does not have the concept of loading individual types, such as Java. The .NET types are implemented in assemblies and to use them ("load them"), you need to load the assembly that defines the type. Under covers, type references include both the type name with the name of the type of names, and the assembly in which the type is specified. In general, types that have the same name as the namespace name but live in different assemblies are considered different. For example, type MyNamespace.MyType, Assembly1 and MyNamespace.MyType, Assembly2 . Note that the assemblies themselves also have a full name; it includes the assembly name and public key token. This allows the two companies to create both an assembly called "Foo" and not to confuse the CLR (provided, of course, that they are signed with different keys). Thus, in essence, it takes several steps to load a type: find an assembly whose type is defined, load that assembly, and then load the type.

Typically, different .NET platforms use different keys to build platforms, such as mscorlib. Now you may wonder how you can use types from Silverlight in the .NET Framework. The reason for this is because the CLR has the concept of a build failure. A build restriction allows the .NET Framework to handle links to Silverlight mscorlib as links to the desktop version. This is true since Silverlight mscorlib was designed as a subset of the version of the .NET Framework (for a specific combination of versions).

Although it may sound like a silver bullet to overcome all the differences in the shape of the fingers, in fact it is not. Over time, various fax assemblies were chosen on different platforms. Take, for example, ICommand. It is available in .NET 4 and Silverlight 4. However, in WPF it is implemented in PresentationCore.dll, and Silverlight in System.Windows.dll. To understand why the PCL does not expose ICommand when you target .NET 4 and Silverlight 4, let's see what happens if the PCL exposes it.

In PCL, we have to put ICommnad into the assembly. We could either choose to use the Silverlight assembly, or the full framework. Regardless of which one we choose, the type will not be resolved on another platform, because PresenationCore.dll exists only in .NET 4 and System.Windows.dll exists only in Silverlight 4.

We solved this problem by resolving the links to ICommand in System.Windows.dll for success in the full structure. How did we do this? The answer is type redirection. Type forwarding allows the assembly to say "I define the type Foo." When the CLR tries to load the Foo type from this assembly, the assembly actually says "no, no - the Foo type is actually defined in this other assembly panel." In other words, the Foo assembly contains something like a pointer to a version of the Bar type. We call these pointers forwarding types.

This concept allowed us to resolve the ICommand mismatch by adding System.Windows.dll to the full structure, which contains the type that goes over to the actual implementation. PCL now gives you ICommand in System.Windows.dll and can be sure that type load requests can succeed on both the .NET Framework and Silverlight. However, this requires at least .NET Framework 4.5 to be oriented, since previous versions did not have forward type.

For all APIs that need to be open, but we don’t work with platform owners to close the gaps. To do this, we have two strategies:

  • We ask platform owners to add missing APIs or to go ahead
  • We ship the portable implementation out of band. Take, for example, Async or HttpClient .

However, simply adding it to the PCL does not work.

EDIT: If you skip a feature in PCL, you can always unlock yourself. Our tester Daniel wrote a blog post that showed several methods that you can use.

+10
source

NOT. STOP.

Well, since this is not what you want to hear, continue at your own risk. :) This, of course, is not supported, and IANAL, so I do not know if this will be allowed by the license agreement.

It seems that the main problem you are facing with existing solutions is that you cannot select individual APIs to add to your portable profile. To do this, you can use ildasm in existing link assemblies, then add the APIs you need (perhaps by copying them from the results of running ildasm on another reference assembly), and then use ilasm to create your own versions of the assembly link with these additional APIs.

You will need to delay the sign and / or disable the verification of the strong key of the key for the keys for modifications that you modify in this way.

Another option is to use type redirection as described in my answer here . In this case, you will have shared access to your main code, as is, with a dependency on the DLL, which will be different for each platform.

+4
source

All Articles