By now, I hope most of you have started exploring .NET 4.5 and VS2012. There are several new features in .NET 4.5 for the developer community. You can find these new features here.
In this article, we will see what is a Portable Class Library (PCL) and its importance. PCLs are used to build portable assemblies which work across platforms like Windows 7, Windows 8, Windows Presentation Foundation (WPF), Silverlight, Windows Store Apps and Windows Phone apps. This project supports subset of assemblies from .NET Framework, Silverlight, Windows Store apps and Silverlight. One of the advantage of this project is that a developer can write the application code once and without modification, this code can be shared across various client applications. This feature increases the re-usability of the application code.
The Portable Library Project, supports the following platforms:
- .NET 4.0 and later. The default is .NET 4.5
- This includes Windows Presentation Foundation (WPF).
- Silverlight 4.0, this is the default selection.
- Silverlight 5.0.
- Windows Phone 7.x, the default Selection.
- Windows Phone 8.
- Windows Store Apps.
- Xbox 360.
Using Portable Class Library Project Template in Visual Studio 2012
Consider the following architecture:
Now-a-days most of the Line-of-Business applications makes use of WPF, Silverlight, Windows Store Apps and even Windows Phone apps. It is a good practice to use patterns like Model-View-View-Model to keep systems loosely coupled. Also MVVM is the standard way for data binding in XAML based technologies like WPF, Silverlight, Windows Phone and Windows Store Apps. So if we have one common layer to maintain Commands, ViewModel and even the Service Adapter (for making call to external service), and make it available to all XAML based clients, then the development efforts can be reduced and the maintenance cost can also be controlled. The Portable Class Library does this for us. We can create it once and make it available to all clients and hence can have a central component for Commands, ViewModel etc.
Practical Implementation of the Portable Class Library
With the theory part out, let’s see how we can implement a Portable Class Library and use it in multiple frontend projects.
For the sample below, I have used SQL Server 2012 with Company Database and the table used is EmployeeInfo as below:
CREATE TABLE [dbo].[EmployeeInfo](
[EmpNo] [int] IDENTITY(1,1) NOT NULL,
[EmpName] [varchar](50) NOT NULL,
[Salary] [decimal](18, 0) NOT NULL,
[DeptName] [varchar](50) NOT NULL,
[Designation] [varchar](50) NOT NULL,
CONSTRAINT [PK_EmployeeInfo] PRIMARY KEY CLUSTERED
(
[EmpNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Task 1: Open Visual Studio 2012 and create a Blank solution
Task 2: In the solution, add a new WCF Service, name it as ‘WCF_DataService’. Set the target framework as .NET Framework 4.5. Rename IService1.cs to IService.cs and rename Service1.svc to Service.svc. Add a new ADO.NET Entity Data Model in the project, name it as ‘Company.Edmx’. Complete the Wizard by selecting Company Database and the EmployeeInfo Table. After completing the Wizard, the Entity Diagram will be as below:
Task 3: Add the following method in the IService.cs:
[ServiceContract]
public interface IService
{
[OperationContract]
EmployeeInfo[] GetEmployees();
}
Implement the above method in the Service class as below:
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
public class Service : IService
{
CompanyEntities objContext;
public Service()
{
objContext = new CompanyEntities();
}
public EmployeeInfo[] GetEmployees()
{
var Employees = objContext.EmployeeInfoes.ToArray();
return Employees;
}
}
Build the project and test the service.
Task 4: In the solution, add the new Portable class library project :
After clicking the ‘OK’ button, pick the target platforms supported by the library
Task 5: In this project, add the reference of the WCF Service created in the Task 2 to Task 3. In this library add a class file, name it as ‘CServiceAdapter.cs’. This will contain a class which makes an asynchronous call to WCF Service.
using System;
namespace CS_PortableClass_Library
{
public interface IServiceAdapter
{
void GetEmployees(EventHandler<MyRef.GetEmployeesCompletedEventArgs> callback);
}
public class CServiceAdapter : IServiceAdapter
{
MyRef.ServiceClient Proxy;
public CServiceAdapter()
{
Proxy = new MyRef.ServiceClient();
}
public void GetEmployees(EventHandler<MyRef.GetEmployeesCompletedEventArgs> callback)
{
Proxy.GetEmployeesCompleted += callback;
Proxy.GetEmployeesAsync();
}
}
}
The above class defines proxy of the WCF service and makes an asynchronous call to it.
Task 6: In the class library, add a new class file, name it as ‘CommandRespository.cs’, this defines class which implements an ‘ICommand’ interface. This class defines constructor with ‘Action’ delegate as an input parameter. This means the command object declared using this class can execute a method without any input parameter. The implementation is as below:
using System;
using System.Windows.Input;
namespace CS_PortableClass_Library
{
public class CommandRespository : ICommand
{
private Action _handler;
public CommandRespository(Action handler)
{
_handler = handler;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_handler();
}
}
}
Task 7: In the class library project, add a new class file, name it as ‘CModelProvider.cs’. The class in this file implements an ‘INotifyPropertyChanged’. The class instantiate the ServiceAdapter class created in Task 5. This also exposes the command property using an object of CommandRepository class created in Task 6. The code is as below:
using CS_PortableClass_Library.MyRef;
using System.ComponentModel;
namespace CS_PortableClass_Library
{
public class CModelProvider : INotifyPropertyChanged
{
public IServiceAdapter Adapter { get; set; }
public CModelProvider() : this(new CServiceAdapter())
{
}
public CModelProvider(IServiceAdapter adapter)
{
if (adapter != null)
{
Adapter = adapter;
EmployeesCommand = new CommandRespository(GetEmployees);
}
}
EmployeeInfo[] _Employees;
public EmployeeInfo[] Employees
{
get { return _Employees; }
set
{
_Employees = value;
onPropertyChanged("Employees");
}
}
public void GetEmployees()
{
Adapter.GetEmployees((s, args) => Employees = args.Result);
}
public CommandRespository EmployeesCommand { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
void onPropertyChanged(string pName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
}
}
}
The command property ‘EmployeesCommand’ will be bound with the XAML element and the Employees property will be bound with the Data-Bound element e.g. DataGrid or ListBox.
Task 8: Build the Library project and make sure that it is error free.
Creating Client Applications
Task 9: In the solution created in the Task 1, add a new WPF project, name it as ‘WPF_Client’. In this project, add a reference of the Portable Class Library.
Task 10: In the MainWindow.xaml, add the DataGrid and the Button element. Define the Class Library Namespace in the XAML and define an instance of the ‘CModelProvider’ class as below:
<Window x:Class="WPF_Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib="clr-namespace:CS_PortableClass_Library;assembly=CS_PortableClass_Library"
Title="MainWindow" Height="486.842" Width="805.263">
<Window.Resources>
<lib:CModelProvider x:Key="vm"></lib:CModelProvider>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource vm}}">
<Button x:Name="btnLoadEmployees" Content="Load Employees"
HorizontalAlignment="Left" Margin="41,45,0,0" VerticalAlignment="Top"
Width="697" Height="66"
Command="{Binding EmployeesCommand}"/>
<DataGrid x:Name="dgEmployees" HorizontalAlignment="Left"
Margin="41,138,0,0" VerticalAlignment="Top" Height="277" Width="697"
ItemsSource="{Binding Path=Employees}"/>
</Grid>
</Window>
If you carefully see the code, the Portable Assembly is registered in the Windows Tag with tag prefix as ‘lib’. The instance of the CModelProvider Class is defined using the key as ‘vm‘. The ‘EmployeesCommand’ is bound with ‘Button’ element. The Employees property is bound with the DataGrid.
Task 11: Run the WCF Service. After the WCF Service starts, run the WPF application. Click on the ‘Load Employees’ button. The result will be as shown below:
Task 12: Add the Silverlight Application in the same solution. Add a reference to the Portable Class library. In the MainPage.xaml, add the DataGrid and the button and set the DataBinding expression to the EmployeeCommand and the Employees property as shown below:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class="Silverlight_Client.MainPage"
xmlns:lib="clr-namespace:CS_PortableClass_Library;assembly=CS_PortableClass_Library"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<lib:CModelProvider x:Key="vm"></lib:CModelProvider>
</UserControl.Resources>
<Grid x:Name="LayoutRoot"
Background="White" Margin="0,0,-320,-164"
DataContext="{Binding Source={StaticResource vm}}">
<Button x:Name="btngetemployees" Content="Button" HorizontalAlignment="Left"
Margin="26,35,0,0" VerticalAlignment="Top"
Width="684" Height="52"
Command="{Binding EmployeesCommand}"/>
<sdk:DataGrid x:Name="dgemployees" HorizontalAlignment="Left"
Height="297" Margin="26,133,0,0" VerticalAlignment="Top"
Width="684"
ItemsSource="{Binding Path=Employees}"/>
</Grid></UserControl>
Run the Silverlight application and the result will be as below:
Task 13: In the same solution, add a new Windows Store Application, name it as ‘Windows_Store_Client’. In this project, add the reference of the Portable Class Library. Add the following XAML in the MainPage.Xaml. Register the Portable class library in the ‘Page’ . Add the Button element and the ListBox in the XAML. The code is as below:
<Page
x:Class="Windows_Store_Client.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows_Store_Client"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:lib="using:CS_PortableClass_Library"
mc:Ignorable="d">
<Page.Resources>
<lib:CModelProvider x:Key="vm"></lib:CModelProvider>
<DataTemplate x:Key="emptemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding EmpNo}"></TextBlock>
<TextBlock Text="{Binding EmpName}"></TextBlock>
<TextBlock Text="{Binding Salary}"></TextBlock>
<TextBlock Text="{Binding DeptName}"></TextBlock>
<TextBlock Text="{Binding Designation}"></TextBlock>
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
DataContext="{Binding Source={StaticResource vm}}">
<Button x:Name="btnloadEmployees" Content="Load Employees"
HorizontalAlignment="Left" Margin="96,64,0,0"
VerticalAlignment="Top" Height="92" Width="1137"
FontSize="22"
Command="{Binding Path=EmployeesCommand}"/>
<ListBox x:Name="lstemps" HorizontalAlignment="Left"
Height="393" Margin="96,233,0,0"
VerticalAlignment="Top" Width="1137"
ItemsSource="{Binding Path=Employees}"
ItemTemplate="{StaticResource emptemplate}"/>
</Grid>
</Page>
Task 14: Run the Windows Store App. The result is as shown below:

Conclusion
Using Portable Class Library, it is possible to create an application layer which can be shared across various clients. Typically this project template is more useful for MVVM pattern application.
Download the source code (GitHub)
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @
maheshdotnet or connect with him on
LinkedIn