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.

Tuesday, August 7, 2012

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