Practical Messaging Scenarios with WCF 4
Friends don’t let friends do point to point. Anyone who has designed services to solve a business problem or built a distributed composite application using service-oriented techniques has, consciously or not, discovered the hazards of client applications knowing too much about all of the services with which they interact.
There are two main reasons for this. First, the more a client knows about a service, the less flexibility the client and the service have to change and evolve. And since one of the principal reasons for distributing components as services in the first place is reuse, factoring service into cohesive functions and defining explicit boundaries between how the client interacts with, or consumes the service is key. Second, the cost to integrate an application increases in proportion to the number of endpoints (interfaces) required to deliver the desired business value. This cost is manifested not in only establishing each initial interface, but also in managing change across the interfaces. These two factors create significant friction because they encourage application designs that exhibit low coupling, but at the same time the value of an application that isn’t connected to anything quickly approximates zero.
Some common problem domains in messaging scenarios that today’s composite application developer must reason about include:
- Factoring the business domain into the right number of services promoting cohesion and reuse.
- Whether orchestration and workflow should take place on the client or the service (i.e., who manages the composition of interfaces)?
- Achieving loose coupling between the client and the service so that each can evolve independently.
- Managing different versions of the service in a manner that is transparent to the client application.
- Handling differences in compatible protocols between the client application and service(s).
- Decoupling the logic that determines which other parties/endpoints may be interested in an event originating from a client application.
- Translating the message representation from a client application to one or more services while the message is in flight.
In the May/June 2010 issue of CODE Magazine, I introduced many of the new features in WCF 4 that help make developers more productive including a simplified configuration experience and the support for WS-Discovery, both of which help developers focus on business value rather than plumbing. These features are undeniably valuable regardless of the messaging patterns you employ.
In this article, I’m going to build on the productivity improvements in WCF 4 by spending some time looking at some common integration scenarios facing those who build distributed composite applications and how common integration patterns help address these scenarios. I’ll then provide an introduction to the Routing Service in WCF 4 and dedicate the rest of the article to showing you how you can address common messaging scenarios by implementing discrete (or combining) integration patterns to address these scenarios quickly and easily using the Routing Service in WCF 4.
Note that design patterns (and even more specifically integration design patterns) are a big topic and very well documented in various bodies of work (see sidebar Favorite Books on Patterns). As such, my goal is not to provide a treatise on design patterns or integration design patterns. Instead, in the true spirit of pattern language, I will take an implementation technology agnostic scenario-driven approach to talk about some of the most common scenarios you are likely to come across that will force you to consider breaking away from the point-to-point integration techniques with which you already may be comfortable. I’ll focus on the scenarios I encounter and corresponding patterns I regularly apply in my own work helping clients, along with rationale for why each pattern might be helpful within each scenario.
With these foundations in place, I’ll shift focus to how these patterns can be implemented with the new Routing Service and then I’ll tie many of these patterns together in a practical business scenario which will reflect how patterns often come together as interdependent pattern clusters to address common messaging problems head on.
A Quick Word on Patterns
What Is a Pattern?
Whether you realize it or not, patterns are everywhere. Consciously or subconsciously, we use patterns every day to solve common programming problems. When we don’t realize that we are using a pattern, we may be falsely led to believe that we are doing something stupendous and unique. However, when we are approached by the same or similar problem in our next work, chances are we will reach for the same approach we found was helpful in solving the “original” problem in our previous work.
This is precisely the idea behind design patterns. Put simply, a design pattern is a way to formally document a solution to a design problem so that others might benefit from its application. These solutions are then organized into pattern clusters that form a pattern language. To quote Christopher Alexander, renowned architect (who led the architecture and design for more than 200 buildings across the world) and the father of pattern language: “The elements of this language are entities called patterns. Each pattern describes a problem that occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.”
In software engineering, we often find ourselves faced with similar problems over and over again, and design patterns offer a way forward in addressing these problems in a manner that is not only proven, but provides the designer with the necessary lubrication to revisit the solution and apply successively more sophisticated extensions of the pattern as a system matures and becomes more complex in response to change. Careful study and practical experience applying design patterns leads to emergent architecture resulting in systems that are responsive to and embrace change. This means that if we stop to consider how other smart people have solved a particular design challenge that may seem incredibly unique, we will not only deliver value to our customers faster but significantly increase the shelf life of the applications that we build!
Many bodies of work document design patterns in various problem domains and texts such as “Design Patterns: Elements of Reusable Object-Oriented Software” by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. In addition, “Patterns of Enterprise Application Architecture” by Martin Fowler belongs on the shelf of any developer or architect who wants to be equipped with a toolbox for solving recurring problems in software design.
In the domain of integration patterns, Gregor Hohpe and Bobby Woolf authored a highly influential book on integration patterns called “Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions.” Throughout this article, I will refer to various patterns from this work, as well as a pragmatic collection of generalized patterns contributed by notable authorities on patterns (including Gregor Hohpe) organized by the Microsoft Platform Architecture Guidance Group (PAG) into a single work called “Enterprise Solution Patterns” but will leave more in depth study of these patterns as an exercise for you.
Finally, it is important to understand that patterns generally fall into three categories:
Architectural and design patterns should, by their very definition, be platform and product agnostic, such that anyone can reason about the fitness of a pattern without regard to a specific vendor technology. Let’s take a moment to define each.
In his 1996 work, Pattern-Oriented Software Architecture, Frank Buschmann defines an architectural pattern as one which “…expresses a fundamental structural organization schema for software systems. It provides a set of predefined subsystems, specifies their responsibilities, and includes rules and guidelines for organizing the relationships between them.”
Erich Gamma, contributing author to Design Patterns: Elements of Reusable Object-Oriented Software cited previously, defines a design pattern as follows: “A design pattern provides a scheme for refining the subsystems or components of a software system, or the relationships between them. It describes a commonly recurring structure of communicating components that solves a general design problem within a particular context.”
Lastly, the PAG defines an implementation pattern as a “low-level pattern specific to a particular platform. An implementation pattern describes how to implement particular aspects of components or the relationships between them, using the features of a given platform”.
For this article, I am going to presuppose that we have decided on a distributed application or service-oriented architecture pattern. I’ll take a platform agnostic approach that focuses on scenarios and forces that might lead to the selection of a specific pattern or group of design patterns, and will provide you with very specific implementation patterns or recipes for realizing these design patterns with the WCF Routing Service.
Now, I want to elevate this focus to a conceptual level to help you understand why re-thinking point-to-point integration might be a good idea. As I progress, I’ll combine explicit pattern language to show you how you might accomplish the goal of a scenario and will finally walk you through a practical implementation example using the Routing Service.
By: Rick Garibay
With over 13 years’ experience delivering solutions on the Microsoft platform across industry sectors such as finance, transportation, hospitality and gaming, Rick is a developer, architect, speaker and author on distributed technologies and is the General Manager of the Connected Systems Development Practice at Neudesic.
Rick specializes in distributed technologies such as Microsoft .NET, Windows Communication Foundation, Workflow Foundation, and Windows Azure to deliver business value and drive revenue while reducing operational costs.
Rick serves as a member of the Microsoft Application Platform Partner Advisory Council and is an advisor to Microsoft in a number of capacities including long-time membership on the Business Platform and Azure Technology Advisors group. As a five-time Microsoft Connected Systems MVP, Rick is an active speaker, writer and passionate community advocate in the national .NET community. Rick is the Co-Founder of the Phoenix Connected Systems User Group, celebrating four years in operation.
Recent presentations include talks at the Microsoft SOA and Business Process Conference in Redmond, WA, Microsoft TechEd, DevConnections, .NET Rocks, Desert Code Camp, and numerous Microsoft events throughout North America. Rick is a frequent contributor to industry publications such as CODE Magazine, and is the co-author of Windows Server AppFabric Cookbook by Packt Press.
When not immersed in the work he loves, Rick enjoys mountain biking and spending time with his wife, Christie and two children, Sarah and Ricky.