June 2009 - Posts

Using WCF 4.0 XAML Services in the real world: Activating WCF Services from a central repository

Declarative Services is one of the new features included in the .NET framework 4.0. In a nutshell, declarative services are WCF services modeled and implemented entirely in XAML. This feature is fundamentally enabled by extending Windows Workflow Foundation (WF) 4.0 with the capability of modeling WCF contracts using XAML. You can read more details about declarative services on the MSDN documentation. Even if you are not entirely familiar with WF as a technology, I am sure you can see the advantages of implementing services in a declarative languages.

Some of the most challenging aspects of Service Oriented (SO) solutions such as versioning, management and governance are notably increased by the fact that most enterprise web services are developed entirely using imperative languages such as C# or Java. Why is that? Well, to give you an example, think about the process that we have to go through in order to change a WCF services that has been running on a production system. In the best case, this process will involve deploying some assemblies to the GAC or to a particular directory, changing some references and restarting some service hosts. Now multiply that order of complexity by the number of services you have on your enterprise and the best you are going to get is a huge headache :)

In order to address some of these challenges, many developers have turned to dynamic languages such as Ruby or Python looking for a more declarative approach to implement services. Although none of the WS stacks built on dynamic languages is nearly as powerful as WCF they are certainly easier to modify and maintain. Declarative services represent an evolution of this paradigm that leverages the benefits of the XAML WF dialect.

XAML-only workflows has become one of the most popular features of the first two versions of WF. The ability of writing logic using an XML-based language drastically improves the versioning, management and other important aspects of software solutions based on WF. Declarative services can be seen as an attempt to extend the same benefits onto the world of WCF services.

In medium to large environments, one of the great benefits of declarative services would be the ability of centrally store the service definition and implementation in a database or any other data repository. This approach will improve the ability to version, modify, document or query services while still leveraging all the capabilities of the WCF runtime. For instance, we could envision a solution on which a custom WCF service host that loads declarative services dynamically from a database. The following diagram illustrates that approach.

 

 

It turns out that there is a simple but elegant solution for implementing this pattern using WCF-WF 4.0. Let's start with the following database that can be used host XAML service definitions as well as part of the endpoint address configuration.

 

Fundamentally, a declarative service definition will be stored in the XAMLService table. Essentially the service column will store the XAML implementation and contract of the WCF service. Additionally some of the details associated with the service host will be kept in the HostConfig table. This is not a real world examples by any stretch of the imagination. On the contrary, we are trying to keep things as simple as possible in order to correctly illustrate the fundamental concepts.

We will abstract the communication with the database using an ADO.NET Entity Model that maintains an almost one to one mapping with the physical database.

 

 

Having completed the ADO.NET EF model we can implement a custom WCF service host that dynamically loads the service definition from a database and initializes it using the existing XAML services functionalities.

   1: public class WorkflowRepositoryServiceHost: 
   2:             System.ServiceModel.Activities.WorkflowServiceHost
   3:     {
   4:         private Guid serviceID;
   5:         private static XAMLService currentDBService;
   6:  
   7:         public WorkflowRepositoryServiceHost(Guid serviceid):

8: this(LoadServiceDefinition(serviceid),

BuildServiceEndpoints(serviceid))

   9:         {
  10:  
  11:         }
  12:  

13: public WorkflowRepositoryServiceHost(Service serviceDefinition,

params Uri[] baseAddresses) :

  14:             base(serviceDefinition, baseAddresses) 
  15:         {
  16:             ServiceMetadataBehavior mtdBehavior = new ServiceMetadataBehavior();
  17:             mtdBehavior.HttpGetEnabled = true;
  18:             this.Description.Behaviors.Add(mtdBehavior);           
  19:         }
  20:  
  21:  
  22:         protected override void OnOpening()
  23:         {
  24:             base.OnOpening();
  25:         }
  26:  
  27:         private  static Service LoadServiceDefinition(Guid serviceid)
  28:         {
  29:             XAMLDBEntities entities= new XAMLDBEntities();

30: IEnumerable<XAMLService> query= from s in entities.XAMLServices

where s.id == serviceid select s;

  31:             if (query.Count<XAMLService>() > 0)
  32:             {
  33:                 List<string> endpoints = new List<string>();
  34:                 MemoryStream stream = new MemoryStream();
  35:                 currentDBService= query.First<XAMLService>();

36: XElement.Parse(currentDBService.Service, LoadOptions.None).

Save(stream);

  37:                 stream.Seek(0, SeekOrigin.Begin);
  38:  
  39:                 Service service = (Service)XamlServices.Load(stream);
  40:  
  41:                 return service;
  42:             }
  43:             else
  44:                 return null;
  45:  
  46:         }
  47:  
  48:         private static Uri[] BuildServiceEndpoints(Guid serviceid)
  49:         {
  50:             if (null == currentDBService)
  51:                 LoadServiceDefinition(serviceid);
  52:  
  53:             List<Uri> uris = new List<Uri>();
  54:             currentDBService.HostConfigs.Load();
  55:             var endpointQuery = from e in currentDBService.HostConfigs select e;
  56:             foreach (HostConfig c in endpointQuery)

57: uris.Add(new Uri(String.Format(http://localhost:{0}/{1},

c.Port, c.Path)));

  58:             return uris.ToArray<Uri>();
  59:         }
  60:     }

Essentially, our custom service host extends the default workflow services (lines 1-2) and dynamically instantiate a XAML service (line 39) together with parts of the endpoint configuration from the database (lines 48-59). In this model, the service implementation could be updated real time in the database without any further deployment actions. The changes will be effective the next time the host starts.

Even though this is a very simplistic scenario, hopefully it will give you a starting point to realize the benefits of declarative services in traditional service oriented environments.

SOAWorld 2009 session

Thanks to all the folks who attended to my session about WOA at SOAWorld 2009. I got a lot of interesting questions from an always sharp New York audience :). You can get the slide deck here…

Speaking at SOAWorld 2009

This afternoon I will be presenting a session about Web Oriented Architectures (WOA) at SOAWorld. The session explores the concepts behind real world architectures based on the principles of REST and how they represent an interesting alternative to traditional SOA.

The SOAWorld team always manages to put together a great speaker lineup including some of the top SOA practicioners in the world. Among many other things, I would recommend attending to the "Business Value" panel that Anne Thomas Manes and Miko Matsumura will deliver tonight.

We are still hiring...

As you might be aware, Tellago (my new venture ) has been steadily growing during last year. We are still looking for talented architects that would like to join our team. Specifically, we are have a few openings for BizTalk Architects and developers. If you are skilful with BizTalk technologies and you are crazy enough to join our team please drop me a line at jesus dot rodriguez at tellago dot com or at jobs at tellago dot com.

Speaking about WCF and WF 4.0 at VSLive

Next Monday I will be presenting two sessions at VSLive Las Vegas. The first session is about the WCF 4.0 extensibility model and it covers almost all the major extensibility points of the different WCF subsystems such as messaging, security, instancing, etc.

The second session is about building services using WCF and WF 4.0. Here we will cover some of the major changes in the WF 4.0 programming model that improve the service development and management experience

I am trying to keep both sessions very practical which means we are going to spend a lot of time in Visual Studion going through code. Additionally, as much as possible, the demostrations will highlight real world scenarios that will give the audience a better sense of how to better take advantage of this technologies.

If you attending to VSLive and you are interested on WF and WCF 4.0 you should come to my session. I promise to keep things interesting ;).

More Posts