Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Tuesday, July 7, 2009

How to get the Using statement to work when dealing with interfaces directly.

UPDATE 2009-08-04: As pointed out in the comments by Marc L there are some issues involved in using the techniques described below the primary problem concerns the fact that you might incur an exception in the finally block of the using statement this would lead to any code below the using statement to not run. Also if you throw an exception in your code and the dispose call yeilds an exception this will mask your exception which you will never see. You can read more about it in this msdn article: Avoiding Problems with the Using Statement

Just recently I did some coding in a project and was faced with something that took me awhile to figure out so I thought I'd write a line or two about it. But before we continue let me state that this post deals with WCF based services in a VB.NET application.

The thing is that personally I'm not very fond of using the "Add Service Reference" in Visual Studio (there are obviously situations where it is useful but most of the times I prefer to have more control over the generated proxy), so what I usually end up doing is to spawn up my own proxy using the ChannelFactory and simply add a reference to the assembly containing the service contracts.

The problem arises when you start working with interfaces to make sure that you can inject your dependencies into your code to be able to implementing proper unit-test. When you do this and try to use the Using statement to implement the disposable pattern and make sure your resources are release in a timely fashion.

Dim factory As ChannelFactory(Of IMyService) = New ChannelFactory(Of IMyService)("MyBinding")
Dim myInterface as IMyService = factory.CreateChannel()

Using myInterface
...
End Using
This example code will generate the following complier error:

'Using' operand of type '…IMyService' must implement 'System.IDisposable'.

So after banging my head against the monitor for awhile I stumbled upon a blog with an example where the author used the As operator to perform a cast in the using statement, so I figured that this hade to be doable in VB.NET as well.

Dim factory As ChannelFactory(Of IMyService) = New ChannelFactory(Of IMyService)("MyBinding")
Dim myInterface as IMyService = factory.CreateChannel()

Using DirectCast(myInterface, IDisposable)
...
End Using

The above code will work and even though it isn’t as slick as it’s counterpart in C# it will do the trick. Now we are able to both utilize the disposable pattern to make sure we are not forgetting to release our resources and still make use of dependency injection in our code and improve our testability.

There is no magic here once you think a little about it what the using statement wants is simply a reference to an instance that implements the IDisposable interface which the proxy returned by CreateChannel does. So we just need to give the compiler a little nudge to get it to work.

UPDATE 2009-08-04: However the problems don't stop here. If we wrap an object implementing IDisposable inside a using statement and the Dispose method throws exceptions we are toast. This will lead to all kind of weird behaviours when dealing with error situations.

First out we need to handle the fact that any exception being raised within the using block will be supressed by exceptions raised from inside the Dispose call. Secondly we have the issue that if you have any code that needs to be executed after the using block, you will be in for a nasty suprise since it will not run if an exception is raised from within the dispose method.

The easiest way to get around this would be to implement a helper object dealing with the disposing logic that we can pass to the Using statement. This object can then supress any exceptions being raised during disposal and do the appropriate logging. The code below implements such a wrapper object that will handle this for the WCF scenario, you could easily modify it and just pass in any object implementing IDisposable and just deal with the logging and exception suppression.

Imports System
Imports System.Diagnostics
Imports System.ServiceModel

Namespace DisposablePattern

Public Class CommunicationObjectScope
Implements IDisposable

Private scoped As ICommunicationObject
Private disposed As Boolean = False

Public Sub New(ByVal co As Object)
If TypeOf co Is ICommunicationObject Then
scoped = co
Else
scoped = Nothing
End If
End Sub

Public Sub Dispose() Implements IDisposable.Dispose
Try
If Not disposed Then
If Not scoped Is Nothing Then
Select Case scoped.State
Case CommunicationState.Faulted
scoped.Abort()
Exit Select
Case Else
scoped.Close()
Exit Select
End Select
End If
End If
Catch ex As Exception
'TODO: replace with more approriate logging!!!
Trace.WriteLine(ex.ToString())

'NOTE: Do NOT throw or rethrow from within this
' exception block since this will mask the
' original exception.
End Try
End Sub
End Class
End Namespace



By using this class we would end up with code looking like this:

Dim factory As ChannelFactory(Of IMyService) = New ChannelFactory(Of IMyService)("MyBinding")
Dim myInterface as IMyService = factory.CreateChannel()

Using co As New CommunicationObjectScope(myInterface)
...
End Using

To summarize you can use the DirectCast approach if you have controll of the object implementing IDispsable, but if there is the slightest chance that an exception might occur from within the Dispose method you should go for the wrapper approach.

Monday, November 3, 2008

Finally a application server for .NET (Codename "Dublin")

I've been waiting for this since the day Microsoft announced .NET without providing a .NET specific host environment. We have been left to host our components in COM+ for several years now, this has work ok but in my personal opinion this has lead to a to tight tie into a technology that had been declared as a legacy technology. This fact has at least for us lead to a slower adoption pace of .NET than we would have had liked.

Anyway enough with the history let look forward. But before we do this lets resolve any issues concerning BizTalk. Microsoft are very clearly stating that "Dublin" is NOT a BizTalk Killer... BizTalk is still Microsoft solution for integration and will continue to be release on a bi-annual schedule as it looks now. Also there are no plans to add functionality to "Dublin" for rich transformations like BizTalk is capable of.

Dan Eshner held a very good session at the PDC08 called "Dublin": Hosting and Managing Workflows and Services in Windows Application Server about how "Dublin" works, I've taken the liberty of using some of the pictures in his slides. "Dublin" or Windows Application Server Extensions as which is the current official name, is a set of extensions that builds ontop of Windows Process Activation Services (WPAS/WAS) which lets us host both workflows (WF) and services (WCF).

The "Dublin" mantra is ... IT JUST WORKS ... and I must say that the stuff we saw at the PDC08 looks promising. One really neat feature that aligns very well with this ambition is the import/export feature, which lets us deploy our binaries along with the correct configuration with a simple click. Under the covers this feature uses a new tool which is already in Beta 2 called MSDeploy you can read more about this tool at the MSDeploy team blog.



As you can see in the picture above "Dublin" consists of:

A runtime database storing all the configuration and data concerning durable services as well as tracking and monitoring.
A management api built using powershell commandlets which makes it very neat to use in regards to operationa task since we can very easily script very complex scenarios. We also get a nice set of management tools that utilize these commandlets build into the IIS management console.
A set of services in the middle consisting of:
Hosting, a part from dealing with the actual hosting of the workflows and services we will get support for discovery protocols and an service that will look for orphaned service calls and restart them if a catastrophic failure occurs (I'm guessing this is a config option since it will require some design considerations when implementing the service in question for instance we would need to deal with the fact that the service needs to be restartable and can't leave partially finnished work).
Persistance, we get a new and improved persistance provider for our workflows which now is cluster aware. So we can have multiple boxes handling the same queues without stomping all over each other.
Monitoring, we get support for montitoring and tracing both workflows (WF) and services (WCF).
Messaging, this is supercool we get a built in forwarding service which lets us do things such as routing based on data in the message (much like the parameter propagation in BizTalk) and we also get support for message correlation based on data within the message payload.
Another cool management feature is the support for persisted instances which is very similar to the way BizTalk manages this for example we can view persisted instances that has failed grouped by exception and much more (see the webcast by Steven W. Thomas mentioned below for more details on how this works).

Nothing in the presentations at the PDC08 talked about build in declarative transactional support such as we are use to in the COM+ environment, however Dan Eschner confirmed in the Q&A that it is on the roadmap for the product but not in v1.

There is also integration with "Oslo" modelling initiative which will enable us to model our service configurations using M and then deploy them directly to "Dublin".

So when will we see this as RTM? At PDC08 they talked about being released about 3 months after Visual Studio 2010 which in turn has been indicated to be appearing around the end of 2009 (which would correspond nicely with how Microsoft has released VS previously) however these dates are purely speculative. It will be released as download for Windows Vista, Windows 2008 and Windows 7 and it will be a part of the operating system in future versions.

For more information take a peek at:

Steven W. Thomas of biztalkgurus.com has produced a webcast which will guide you through how the "Dublin" management extensions in IIS manager will look like.
First Look at Windows Application Server (Dublin)
As always David Chappell has written a good overview of "Dublin" and a bunch of related stuff (this is a very quick introduction to the technologies it doesn't go very deep).
Workflows, Services, and Models -- A First Look at WF 4.0, “Dublin”, and “Oslo”
Finally I found a rather good FAQ like document at Microsoft which gives some more insights in what going on with "Dublin" in conjunction with .NET 4.0 (also a small document).
Riding the Next Platform Wave: Building and Managing Composite Applications

I hope this has given some insights into "Dublin" and look for further postings in the future since this is an area which I intend to dig deeper into.