Showing posts with label Portable Library. Show all posts
Showing posts with label Portable Library. Show all posts

Monday, October 29, 2012

Portable Class Libraries [PCL] : Targeting Additional Frameworks

In this post, we will continue our discussion on Portable Class Library in Visual Studio. This allows us to target the same assembly to multiple frameworks, which allows to use the same assembly without even a need of recompilation.

Previously we have discussed about the following:
  1. An Introduction : http://www.shujaat.net/2012/07/multi-plaftorm-targeting-using-portable.html
  2. Portable Class Libraries & MVVM : http://www.shujaat.net/2012/08/portable-class-library-mvvm.html
  3. Portable Class Libraries & Features Support using Profiles : http://www.shujaat.net/2012/08/portable-library-tools-supported.html
  4. Portable Class Libraries & Type Forwarding : http://www.shujaat.net/2012/08/portable-library-tools-type-forwarding.html
As we know that the portable class library tools now support targeting the library to multiple frameworks including .net framework versions, silverlight versions, Windows Phone versions, Windows Store App and Xbox 360. What if we want to target it to a .net platform which is not listed including mono platforms?


Targeting additional Framework & Usage of Profiles
In order to determine how we would be supporting the framework in Portable Library Tools, we first need to determine the feature set supported by the target framework. We must also consider how those features are supported. During our type forwarding related discussion for portable libraries, we tried to ponder on why it is important to know how the features are provided and that is why MVVM types are not supported with portable class libraries for .net framework 4.0 as they are differently provided than rest of the platforms.


These profiles allow Visual Studio to provide framework lists for portable class library projects. Based on this idea, we should be able to add remove the frameworks and their versions by manipulating these profile folders. To get started, let's move all the profiles from the .NetPortable folder.


Now create a Portable Library Project and see the empty target framework lists. Now it should make sense how profiles affect the target frameworks list available for portable class library projects. I am using Visual Studio 2012 RC here.


Skeleton of a Profile
As sample profile folder for a portable class library project consists of some dlls & their xml for documentation of containing types, RedistList folder and SupportedFrameworks folder.


Here all the dlls are retargetable. This means that the portable library would use the versions of these dlls from the host framework. So if the portable library is being used in a Silverlight project then it would be using the Silverlight version of these assemblies. Similarly, if the same assembly is being used in a .net framework based project, it would be using the assembly provided by .net framework version. Let's look at the manifest of System.Core assembly in Profile1. You can also notice that the other assembly references are also from retargetable versions of these assemblies.



Al the profiles seem to share the code documentation. So the xml files contained in the profile folder is just for redirection to the main folder containing all the profiles.


This is just referring to this documentation xml file. This is super smart idea as the main folder would have the complete documentation and all the containing profiles would just be a subset of the main assembly.


Please remember to reload visual studio i.e. kill it and open it again for the changes in profiles to take effect.

Now we come to RedistList/FrameworkList. This is to describe the list of assemblies available for the target frameworks. For Profile1, the list is as follows:


From the xml file, I am sure that you can guess what assemblies would be looked for for the list of the target frameworks. The corresponding assemblies are looked for in the folder containing the Redist folder. There seems to be no exception if an expected assembly is not there in the folder. Also there doesn't seem to any issue if an unexpected assembly is found in the profile folder.


Now which part of profile is important to show frameworks and their versions in framework selection dialog for portable class library project. This is the SupportedFrameworks folder. You will find a list of xml files in the folder.


The text of the framework for the selection comes for the xml content of these files. Display name shows up for the selection. If we just change Xbox 360 to Xbox 360 2 , that is what is shown on the dialog for selection.

This is how the framework selection is shown after the change:


And that is exactly how this is shown in the Library Tab of Portable Class Library project.


Now on Additional Frameworks
After the above discussion, we have found out that the frameworks available for selection are picked up from the xml files from the SupportedFrameworks folder. So in order to target to an additional framework, we need to find out if the new target framework has features that are provided by any of the available profiles. And also the way the profiles are provided.

This is how the framework is available in the selection dialog:


If there are more than one versions of your framework in different profiles then they are displayed in a selection control. Let's copy a new profile [Profile 2] and a new framework file Additional Framework 2.0 with the following contents.


This should result in displaying the framework selection dialog as follows:

Friday, August 17, 2012

Portable Library Tools & Type Forwarding

This post is part of a series of posts where we are discussing Portable Class Library Tools. It allows same library to be targeting multiple frameworks including any combination of .net framework, Silverlight, Windows Phone, Metro and Xbox360 development. In the previous post we discussed how development environment determines what features set to support for a combination of selected environments. We also discussed how we can limit targeting frameworks on development machines.

Here we discussed how common feature set is available for development based on the target frameworks selected. We used a few interface and concrete types including ICommand, ObservableCollection<T> and INofityDataErrorInfo. Basically the availability of these types in a common codebase is in itself a great achievement. This is because these types are defined at different assemblies in different frameworks. Even if we keep the namespace similar then which implementation should be used by the compiler?

Let's first look at INotifyDataErrorInfo. This is available in Silverlight framework as follows:


The same interface is available in .net framework 4.5 at different location. Let's see the following definition:


Similar are the following examples:
  • ObservableCollection<T>
  • System.dll [.net Framework 4 & 4.5 Dev preview], System.Windows.dll [Silverlight]

  • ICommand
  • System.dll [.net Framework 4.5 Dev preview], PresentationCore.dll [.Net Framework 4], System.Windows.dll [Silverlight]
Now if we are targeting for .net framework 4.5 Developer's preview and Silverlight 4 then the observable collection type would be used from System.dll or System.Windows.dll?? In this post we will try to address how this is actually happening inside the hood of portable libraries.

In the previous post, we discussed about reference libraries and profiles. These reference libraries contain the metadata information for these types. The metadata information might be about where to get the actual definition of the type with necessary forwarding details. In order to look at the actual definition, we will be needing to disassemble a reference library. The reference libraries for .net portable can be found here:


The concept of Reference assemblies was introduced in .net framework 3.0. This is to provide design time version of these assemblies. At runtime the assemblies would be directly used from Global Assembly Cache. We have seen in the previous post how profiles are used for targeting a set of selected target frameworks.


As we have previously seen, portable libraries can only be referenced by any of the selected target frameworks specified during development of the portable library. When loaded at runtime it would be using libraries directly from the host framework inlcuding Silverlight and .net framework. So for the case of mscorlib, the library [mscorlib] would be used from "Reference Libraries" folder during development. At runtime, the host framework's version of mscorlib would be used. You might be wondering about the API differences and differences in Types' behaviors for different frameworks. Don't worry about it, some changes were made in .net framework 4 to support just that. You can find the details here:

http://msdn.microsoft.com/en-us/library/gg597392.aspx

Let's look at the following chart:


These are names of types and their relevant assemblies. Most of the types in .net framework are at the same assembly, yet they are supported for portable libraries for .net framework 4.5 and not supported for .net framework 4. That seems quite strange. If they can be used by one then why can't they be used by the other one?? The explanation should cover how type's locations in different assemblies in multiple target frameworks (including Silverlight & .net framework 4.5) is addressed. The whole idea is type forwarding. Please remember that this is not a new concept introduced by Microsoft but this has been there for a while, Portable Library Tools is just cashing into that feature.

Basically, a portable library would always refer a type from the same assembly. Now it would be loaded in a certain framework including Silverlight or .net frameworks (or any other) with the assembly with same identification (e.g. System.Windows.dll). Based on the reference information in portable library, the framework would access the referred type from the same assembly as specified by the portable library. Now it is the assembly's responsibility to either provide the type or direct to some other assembly in the framework as a guidance for the type's location by using TypeForwardedToAttribute. There would be different System.Windows.dll for Silverlight and .net framework 4.5 with different manifest information. In Silverlight this would be directly provided by System.Windows but in .net framework 4.5, System.Windows would redirect the request to System.dll for the types specified in the chart.


The above explanation answers both questions. First, since the portable library always access the types from the same assembly, there is no magic in the portable library itself to for redirection of type's assembly location. It is actually the framework where the assembly is loaded which helps the portable library finding the specified type using type forwarding. Second, since the assemblies with type forwarding information is not available in .net framework 4 [e.g. System.Windows.dll], we can't use types for multitargeting where they are coming from different assemblies. So this Type Forwarding assembly is kind of a mediator. When the mediator is not present, there can't be any portability.


If you are curious like me then you might want to look at the definition of the assembly [System.Windows.dll] in .net framework 4.5. Well we can use ILDASM to see the assembly manifest. Please specially focus on the forwarder attribute for class type being forwarded. Now where to get this type from?? This is specified as ".assembly extern System", which is just saying that, "Look at the definition of this type in System assembly.". This is from the folder [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5] instead of any profile from .NetPortable folder.


Now let's have a look at our portable library to see how System.Windows is referenced. It is referenced as retargetable assembly, which means that it would be loaded based on the host framework [Silverlight, .net framework 4.X etc].


Sunday, August 12, 2012

Portable Library Tools & Supported Feature Set

In the previous post we discussed how we can use Portable Library tools to develop an application. The view model and model libraries were created as portable libraries targeting .Net Framework 4.5 and Silverlight 4 frameworks.

You might be wondering how to determine the features supported in a set of target framework combinations. I have noticed different profiles being maintained for different target framework combinations. These features would be based on the assemblies available in the .Net portable subset.


Basically the available feature set for target frameworks is resolved by maintaining different profiles for each possible combination. If you have Portable Library Tools installed on your machine then you should be able to find the various profiles just for this. I can see the following profiles:


Each of these profiles is about a certain selection of the frameworks. It seems that the selection of frameworks in the framework selection dialog creates the mapping suggesting the selection of a particular profile. The profile has the details of the supported frameworks. The following profile supports .Net for Metro style apps, .Net framework 4.0.3 and Silverlight 5 frameworks.


This is the definition of one of the xml files in the folder shown above.

The profile also has the details of the features supported by specifying the list of assemblies maintained in FrameworkList.xml.


The following profile is for the target frameworks including .NET for Metro style apps, .NET Framework 4, Silverlight 4, Windows Phone 7, Xbox 360). Just look at the minimum features supported as small overlapping area in these frameworks' feature set.

The list grows as we reduce the number of target frameworks. The following is the profile for the selection of frameworks including .NET Framework 4.0.3 and Silverlight 4.

The above libraries are themselves retargetable libraries. We also remember from our last discussions that portable libraries can only reference other portable libraries. We can use ILDASM to verify our claim. Here we are looking at the definition of System.dll for one of the profiles.


Please note that ILDASM is one of the Windows SDK tools. I can find it in the following folder on my machine.

C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools

Now let us discuss a bit how these reference assemblies are used during development. Basically, these are not the files which would be loaded during runtime. At that time, the runtime would load that version of the library which would be supported by host platform. The portable libraries can be loaded by any framework in the list of frameworks they are targeting. These reference libraries just contain metadata specifying where to look for definition of a particular type requested. This is generally a redirection to some other namespace possibly in a different assembly.

Allowing Only Certain Target Frameworks
As we have been discussing that we can target different frameworks including .net frameworks, Silverlight, Metro, Xbox360 and Windows Phone.


Can we exclude certain frameworks? e.g. what if we don't want our development machines to be creating libraries excluding Xbox360. Can we do that? The answer is yes we can.


In order to do that just search the profiles targeting Xbox 360 and remove them from the folder.

Thursday, August 2, 2012

Portable Class Library & MVVM

This is continued from the previous post where we introduced Portable Library Tools from Microsoft. In this post we will be discussing how useful portable library tools are for the incorporation of MVVM for an application which have multiple UI requirements. The application can be consumed by users from different platforms. These might include Silverlight, WPF, Windows Phone and now Metro. Since all of these platforms can be developed in XAML, we don't need to find many developers with platform specific expertise to develop for a particular platform, keeping in mind that the XAML might be closely similar but same XAML cannot be used for these platforms. It might have a different class hierarchy, different defaults and non-matching behaviors. This also helps in shuffling developers across these teams.

Based on the above discussion, we cannot use same view for these platforms. Back in the days, we couldn't even share the view model across these platforms as many MVVM specific features are not available across these platforms, Or they are not provided similarly. With .Net 4.5 and portable libraries, this gap is being minimized. The features available in one platform is being available in the other platform. It's example is INotifyDataErrorInfo. This used to be available only in Silverlight platform. This is used to notify the errors to the interested UI logic. With .net framework 4.5 Developer's preview, this has been incorporated in .net framework. Before this, we weren't able to share the same view models from silverlight to .net framework because of same reason. Even if we minimize the features to better incorporate multitargeting, we still couldn't use the same assembly across these platforms as the assembly is compiled differently across these frameworks.

Portable Libraries make our lives easier by making only those features available which are supported by all of the selected platforms. If we are targeting our libraries for .net framework 4.5 and Silverlight 4 then only those features would be available which are available in both of these platforms. Let's try to understand this with an example. We are using the same concept of CoffeeHouse application as we have been using for a while. But in order to minimize the noise, we are tasked with a simple interface to enter Barista's information. We only need to provide the details about First and Last name of Barista.

Creating Projects and Adding References
Let's first add a portable class library project for holding view models as follows:


Since this is a portable library based project, we can target multiple platforms. As per the requirement, we are selecting .net framework 4.5 and Silverlight 4 platforms.


Similarly, we add another portable library project to hold our models. This project also targets .net framework 4.5 and Silverlight 4.


Since both model and view model based projects are portable library projects targeting the same platforms, we can add the reference of one in other project. In MVVM view model can hold model's instance when model is not aware of the view model it belongs to. This is similar to Dependency Inversion idea where higher level module (view model) uses lower level modules (models). Here we are adding model project's reference to the view model project.


Now we can add WPF and Silverlight projects for UI logic.


Both of them would need a reference of view model's project so that view model types are available to the UI logic.


The project's references are added as follows:


Please notice that the Silverlight and WPF projects are using the same view model and model's libraries which is the core idea of multitargeting.


Adding Model
Let's add a simple model to Model's project to hold Barista's information. It simply has two properties to hold first and last names of Barista.


Adding View Model
Now we need to add view model. The view model needs to provide the view state. It is responsible for passing the state between view and model at appropriate time. It is also exposing properties for first and last name of the barista. It implements INotifyPropertyChanged to provide value change notification for its properties. The view would be using PropertyChanged event to update itself based on the state of the view model. It also implements INotifyDataErrorInfo for validating the view state. It is supposed to raise ErrorsChanged event whenever error state of a property is updated. The property can be updated from valid to invalid state or vice versa. It is maintaining a collection to hold error details of these properties.

The view model also exposes an ICommand, named SaveBaristaCommand. When executed, this should pass on the view state to the model.


ICommand Implementation for Portable Library Tools
Here we can provide a custom implementation of ICommand in view model's project. This has just been used from Josh's article with minor changes. See the following series of posts from Jeremy to find out how portable class library uses type forwarders to locate the definition of ICommand in a non-SL framework.


Silverlight based UI
Let's add simple interface to enter Barista's information. Let's do it first for Silverlight. It just has two TextBox (es) to enter first and last names of the barista. It also has a button, when clicked the values should be passed to the model.

While running, this should look like as follows:


WPF based Interface
Now let's add WPF based interface to the .net framework 4.5 project. As you might have noticed, the XAML is similar but not same. For silverlight, Label is not available in the framework and we need to use it from the toolkit. In order to minimize the noise there, we ended up using TextBlock(s). Additionally, the default binding Mode is OneWay in Silverlight. Since we need TwoWay binding, we needed to explicitly specify so. We don't need this specification for WPF based XAML as the default here is TwoWay. When you run it, you might miss the error message which is available in Silverlight. this appears when INotifyDataErrorInfo specifies the presence of error for a property. Although the control is highlighted in WPF, we need to provide additional logic to display the actual error message(s).


When executed, this should look like as follows [This is similar to the Silverlight based UI]:


Existing MVVM Frameworks and Toolkits
Although it would be a big relief for most of the developers who are maintaining different versions of their libraries for specific platforms. If they were already writing multitarget enabled code, then they were still using the features which were overlapping across these frameworks. With Portable library tools, this has been taken care for them. We would just need to maintain one set of libraries which support multi-targeting for the selected platforms.

The only caveat is the already existing MVVM frameworks and toolkits which are used heavily for our MVVM designs. Since Portable libraries can only reference other portable libraries supporting the selected frameworks so we wouldn't be able to use the existing frameworks and libraries. As for our code, we needed to provide our own implementation of ICommand [RelayCommand]. Since the portable feature is so promising, I am sure that the frameworks and toolkits authors are already thinking about it.

http://mvvmlight.codeplex.com/SourceControl/network/forks/onovotny/MvvmLightPortable

Download Code