Thursday, June 17, 2010

Calling WCF service without AddReference

One of my Silverlight blog post is about creating a proxy without using the add reference menu in the Visual studio.The solution there is to write all the code which is auto generated when we add the reference through the proxy.ie we are just avoiding the auto generation and writing ourselves.Not a good solution.The reason we need to write all is because Silverlight supports only the Async service calls.But if we consider WPF we can call the service in Sync way.That means we can try out new things which will reduce our works in creating the manual proxy.

Didn’t get anything? In short we are going to create a proxy and call service without using the Add Service Reference menu or the any of the tool (eg:svcutil)available for generating the proxy.How can we achieve that.It’s simple .Share the contract dll.Important thing here is the sharing of contract dll is possible only because WPF and the WCF is using the same framework and runtime.This will not be possible in case of Silverlight since the runtime is different.

Ok.Lets start.We need 3 projects mainly.One is the Contracts where we keep all the WCF contracts.Then a service host project and a consumer of services.In the attached sample the host is a web host and the consumer is a WPF application.We can also host the WCF service in ConsoleHost.But in that case we need to solutions.Thats why I decided to go with WebHost.Below is solution structure.
Note that there is no ServiceReference in the WPF UI project.Only thing is the reference to Core project which contains all the contracts.App.Config should be same as of normal proxy creation in case you want to use default connection settings.All the magic happens inside the ServiceProxy class which is inheriting the ClientBase with a generic class.It will be clear after seeing the code below.
Imports System.ServiceModel
Imports ManualProxyTest.Core
Public Class ServiceProxy
    Inherits ClientBase(Of IMyService)
    Implements IMyService
    Public Function GetData(ByVal value As Integer) As String Implements IMyService.GetData
        Return Me.Channel.GetData(value)
    End Function
    Public Function Divide(ByVal no1 As Integer, ByVal no2 As Integer) As Double Implements IMyService.Divide
        Return Me.Channel.Divide(no1, no2)
    End Function
    Public Function GetChar(ByVal data As String, ByVal position As Integer) As Char Implements IMyService.GetChar
        Return Me.Channel.GetChar(data, position)
    End Function
End Class


For calling the service just create the instance of ServiceProxy and call as usual.Main advantage is the cleanliness in the code and we will have full control over the code.

Saturday, June 12, 2010

Common Code Base 1 Introduction

The thoughts on common code base or single code base for both desktop applications and internet applications has been started with introduction of C# in Silverlight 2. That brought not only the same design and coding languages into WPF and Silverlight but also the same APIs.

Same coding language was used earlier too.It was for Windows forms and ASP.Net.Even we were able to share the assemblies among them.But we were not able to create same application layer for them since the APIs and the design mediums were different.As time evolves Microsoft introduced the concept of XAML and made almost all the APIs same.

As everybody knows still Silverlight is the subset of WPF even in its 4th version.There are so many classes and members missing in Silverlight if we compare with the WPF equivalent.Does that means we cannot go for the common code base?

No.We can go for the approach of common code base as of now.But you cannot have certain WPF specific features in your application.Do your client allows that ? absolutely not.So we need to tackle that situation by providing WPF specific features in the desktop release.That means the road to the single code base is not that much easy as you think. So what is the simpe solution?

The solution is very easy.Develop your application against Silverlight excluding Silverlight specific features such as DeepZoom and compile the same code for WPF.It should work.I am saying this should work because most of the Silverlight classes and their members are available in WPF as same.

This will work if you are developing a simple application without WPF specific features.If you want to use WPF specific features you need to architect your application in such a way that it is following MVVm strictly.MVVm will allow you to switch the views very easily without changing the underlying layers.

Solution structure.

Develop against Silverlight then it will work in WPF. We need to remember this thing while creating the visual studio solution structure.So first create the Silverlight projects and keep the code and xaml files there.Then create WPF projects and link the files from Silverlight project location.Easy..What ever feature you implement in Silverlight or the fixes you do will reflect in WPF application too.

Look at the files MyControl.xaml and MyViewModel.They are real files in the Online solution and linked in Desktop project.

Issues

First issue you may encounter is XAML incompatibility.In WPF when we create a xaml style you normally specify as x:Type Classname.But this x:Type is not at all supported in Silverlight. Silverlight needs just the class name without x:Type .If you look at some of the controls like TreeView ,In WPF this resides in the PresentationFramework dll but in Silverlight it is in System.Windows.Controls.dll so we cannot have same xaml shared between WPF and Silverlight projects.There are so many issues like this.Will discuss about one by one in subsequent posts to make the real common code base.

Sunday, June 6, 2010

WPF 3.5 Bug in inheriting DataTemplate

You can easily reproduce the bug.Just inherit the DataTemplate and use the new DataTemplate class instead of default.You will get an runtime exception.

Your DataTemplate class

public class MyDataTemplate :DataTemplate
{
}


Nothing unusual rite? Then use this DataTemplate in your XAML.

<ListBox x:Name="lstPersons" >
<ListBox.ItemTemplate>
<local:MyDataTemplate >
<StackPanel>
<Button Content="{Binding Name}" />
</StackPanel>
</local:MyDataTemplate>
</ListBox.ItemTemplate>
</ListBox>


Just using the new class.But when we run this we get the exception as follows.


StackPanel' object cannot be added to 'MyDataTemplate'. Object of type 'System.Windows.Controls.StackPanel' cannot be converted to type 'System.Windows.FrameworkElementFactory.

This is true same in the case of HierarchicalDataTemplate too.

This is an identified bug.Microsoft has fixed this and WPF 4 contains the fix.