SOA Patterns Archives - Anuj Varma, Hands-On Technology Architect, Clean Air Activist https://www.anujvarma.com/category/technology/service-oriented-architecture/my-favorite-soa-patterns/ Production Grade Technical Solutions | Data Encryption and Public Cloud Expert Thu, 06 Jul 2017 03:05:05 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://www.anujvarma.com/wp-content/uploads/anujtech.png SOA Patterns Archives - Anuj Varma, Hands-On Technology Architect, Clean Air Activist https://www.anujvarma.com/category/technology/service-oriented-architecture/my-favorite-soa-patterns/ 32 32 SOA Challenges–State Maintenance, Security https://www.anujvarma.com/soa-challenges-state-maintenance-security/ https://www.anujvarma.com/soa-challenges-state-maintenance-security/#respond Mon, 02 Mar 2015 03:04:00 +0000 http://www.anujvarma.com/?p=4840 APIs Computer to computer interactions (see 2-way certificates for Web Service Security). APIs are tightly integrated into client code – Web Services work through a proxy – nothing from the […]

The post SOA Challenges–State Maintenance, Security appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
APIs

Computer to computer interactions (see 2-way certificates for Web Service Security). APIs are tightly integrated into client code – Web Services work through a proxy – nothing from the actual server (except a proxy representation of the service) is needed.  In RESTFul APIs, even the proxy is not really needed  – it is direct HTTP call

State in SOA

– Per Call (new object instantiated for each call) and Per Session (object stays alive for entire session of calls) services.

Operations – 1 way versus Request-Response versus Callbacks  

1-way calls – Fire and Forget

Request Response – Most common pattern

Callbacks 

The client becomes the server – so the client needs to host an HTTP CAllback Object

HTTP cannot be used for callbacks – so WSHTTP and BasicHTTP bindings are both useless (only NetTCP and NamedPipes support Duplex mode)

The post SOA Challenges–State Maintenance, Security appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/soa-challenges-state-maintenance-security/feed/ 0
Agatha–Getting Started–First Application https://www.anujvarma.com/agathagetting-startedfirst-application/ https://www.anujvarma.com/agathagetting-startedfirst-application/#comments Thu, 12 Dec 2013 23:51:00 +0000 http://www.anujvarma.com/?p=1691 Introduction The advent of WCF has made life simpler for web service developers . Passing complex types, quick serialization,  write once run with multiple bindings (and hence multiple consumers) etc. […]

The post Agatha–Getting Started–First Application appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
Introduction

The advent of WCF has made life simpler for web service developers . Passing complex types, quick serialization,  write once run with multiple bindings (and hence multiple consumers) etc. – have contributed to its popularity. However, larger WCF projects start suffering from the following symptoms:

The Proxy Dependence

Each time a parameter is modified (on a service request), the service definition needs to change. This requires an update of the proxy on each client consuming the service.

Agatha’s Solution  – Standardize the request and response – so there is no change in the single contract that all services expose. This single contract looks like :

public abstract Response Handle(TRequest request);

Services and Operations Bloat

Large number of Services, each with multiple Operation Contracts.

Services start overflowing into other services – and lack boundaries.  Each service starts to have too many operations. When adding a new operation, one would be faced with a decision : whether to add it to an existing service or to create a brand new service.

Agatha’s solution – Define custom request types for each operation (e.g. if your operation is to GetEmployeeDetails, you would have a request called GetEmployeeDetailsRequest – and a response GetEmployeeDetailsResponse). Each operation then is simply a Handler for these custom request types. So – GetEmployeeDetailsHandler – would have a single Handle() method to contain your business logic.

This enforces granularity on your service operations – and makes them easier to maintain. You will never have to worry about WHERE to place a new operation. It just gets its own handler, its own request and response types.

No More Initialization, No More XML

A WCF client would need to initialize an instance of each proxy – and then invoke the operations on it. In addition, it would need to ensure that the proxy was up to date (by updating its service reference).

Agatha’s solution – Use an IoC container to discover and initialize all your services (i.e. just a single service the WcfRequestProcessor service).

private static void InitializeAgatha()

      {

          new ClientConfiguration(typeof(AgathaGettingStartedRequest).Assembly, typeof(Agatha.Castle.Container)).Initialize();

      }

Single service, Single endpoint, Common contract

Since all the requests and responses derive from a common agatha Request and Response typesT, all services exchange the same types. Their contract is the same. Only a single endpoint is needed – regardless of how many requests and responses (operations) you may have in your project.

<services>

      <service behaviorConfiguration="RequestProcessorBehavior" name="Agatha.ServiceLayer.WCF.WcfRequestProcessor">

        <endpoint address="" binding="customBinding" bindingConfiguration="binaryXmlOverHttp" contract="Agatha.Common.WCF.IWcfRequestProcessor" />

      </service>

    </services>

 

Getting Started

Having discussed the need for something like Agatha, here is a sample project that shows how to use it (source code  towards the bottom).

Step 1 , Getting Started – Defining Request Types and Response Types

A base Request type is provided by Agatha – to which you can add your request fields. For example, suppose your service operation is one that Creates a new Account. You would define a new Request Type called CreateAccountRequest which would be of (a base) type Request (agatha’s base request type).

public class CreateAccountRequest : Request

  {

      public AccountDTO accountDTO{ get; set; }

  }

namespace Agatha.Common

{

    public abstract class Request

    {

        protected Request();

    }

}

 

Step 2, Getting Started – Adding Service Operations

agatha_solution

 

Step 3a – Registering Agatha Services , Client

Normally, in your WCF client, you would ‘Add a Service Reference’ from within your client project to access a known WCF service. If your client is using Agatha, you can use an IoC container to ‘discover’ the services for you – so you never have to ‘Add a Service Reference’. All you need in your client code is:

private static void InitializeAgatha()

        {

            new ClientConfiguration(typeof(AgathaGettingStartedRequest).Assembly, typeof(Agatha.Castle.Container)).Initialize();

        }

Step 3b – Registering Agatha Services , Server (service)

An IoC container can be used to register and initialize the service within the WCF runtime. Notice that you do not have to worry about any XML configuration (contract name, bindings etc.). All you need is to use the provided ServiceLayerConfiguration class – and initialize it when the web app initializes (Global.asax, application_start).

void Application_Start(object sender, EventArgs e) 

    {

        //  Agatha initialization can happen here

        Bootstrapper.RegisterAgatha();

    }

public static void RegisterAgatha()

      {

          new ServiceLayerConfiguration(Assembly.GetExecutingAssembly(), typeof(AgathaGettingStartedRequest).Assembly, typeof(Agatha.Castle.Container)).Initialize();

      }

What are some other things Agatha can do?

 

Call your services asynchronously

Just as in WCF (or any other async pattern), the actual service itself does not need to be asynchronous. Only the client needs to invoke the service asynchronously from its side. This is accomplished in regular web services using  the BeginInvoke and EndInvoke (or BeginServiceOperation and EndServiceOperation).

  In Agatha, similar constructs exist to enable calling the same service asynchronously from a client. An AsyncRequestDispatcher implementation contains a ProcessRequest method to help with async client requests.

/// <summary>

       /// ProcessRequests is the Asynchronous version of requestDispatcher.Get

       /// </summary>

       private static void CallTheServiceAsynchronously()

       {

           var requestDispatcher = IoC.Container.Resolve<IAsyncRequestDispatcher>();

           requestDispatcher.Add(new AgathaGettingStartedRequest());

          

           // ProcessRequests is the Asynchronous version of requestDispatcher.Get

           requestDispatcher.ProcessRequests(ResponsesReceived, e => Console.WriteLine(e.ToString()));

       }

 

       private static void ResponsesReceived(ReceivedResponses receivedResponses)

       {

           Console.WriteLine(receivedResponses.Get<AgathaGettingStartedResponse>().Message);

       }

       private static void InitializeAgatha()

       {

           new ClientConfiguration(typeof(AgathaGettingStartedRequest).Assembly, typeof(Agatha.Castle.Container)).Initialize();

       }

 

Customize your Request object (e.g. Custom Authentication)

What if you wanted only specific users to access certain services? You would need to pass in a userId with each request. This is easily accomplished by defining a custom base request class – that can be used as the parent for all subsequent requests.

/// <summary>

    ///  A single, centralized request allows passing custom Authentication parameters - e.g. userId.

    /// </summary>

    class CustomizedAuthRequest : Request

    {

        public long userId { get; set; }

    }

OverRide beforeHandle and AfterHandle for custom processing

Agatha provides a base RequestHandler class ( RequestHandler<TRequest, TResponse>) – with several useful template methods. These include Handle, BeforeHandle and AfterHandle methods to provide custom processing. If you wanted all your requests (containing a userId) to be authenticated (against sql server or ldap etc.), you would just need to do it in the BeforeHandle method. The template pattern used in Agatha, is a life-saver here as well, as in other OO codebases.

public override void BeforeHandle(TRequest request)

{

        // e.g. - do custom authentication (LDAP, ActiveDirectory etc.)

    base.BeforeHandle(request);

}

 

public override void AfterHandle(TRequest request)

{

        // e.g. - do custom logging etc.

    base.AfterHandle(request);

}

Single WCF Performance Counter

Remember that Agatha is a generic request response processing layer – and does not need WCF. However, a WCF processor is provided with Agatha – since it is commonly used with WCF. If you look in your performance counters, under ServiceModelService 4.0.0.0 , you should see the WcfRequestProcessor counter that Agatha registers on your local PC. This can be monitored during your testing effort.

WcfRequestProcessor_thumb2

 

What do I need on the client? Agatha Client Side Requirements

Agatha relies on your defining custom request and response classes for each of your operations. The client needs to know what these types are. You DO need to share the assembly containing the common types between the server and the client. And you DO need common Agatha libraries – in particular Agatha.common and Agatha.castle (for Castle Windsor IoC).

However, note that agatha services CAN consumed by non-Agatha aware clients.  It is possible to consume an Agatha service just like any WCF service, as described here.

What about NServiceBus (or service buses in general)?

A service bus does not (typically) do ‘request-response’ well. It relies on a message publishing (and subscribing) – which is not (necessarily) instantaneous and not (necessarily) synchronous. It is, however, fault tolerant (ensuring that messages DO get delivered) – and highly scalable (since instantaneous responses are not mandatory).

For a typical web user, a request-response pattern is more important than a message publishing pattern.

Having said all that, NServiceBus supposedly supports a request-response pattern – in addition to its core message publish subscribe pattern

The sample Hello World project

Project 1 –SharedCommonTypes

The types that are common between the client and the Service Layer

Project 2 – ServiceLayer

The Service Layer itself. This inherits from Agatha’s base RequestHandler class. It overrides the Handle method in the base class. This is all that is REQUIRED in the services layer. Notice that the Service Layer knows nothing of WCF or any other web service technology. All it is – is a pure request – response handling layer.

A static class that provides an initialization method is a good idea – it makes the code on the client much easier.

Project 3 – Agatha Host Site

The blank WCF service that acts as a container. This will allow us to host it within IIS. There is no logic, no operations etc. within this WCF service. It is just a blank service. All service operations are moved to the ServiceLayer – which has a custom Handle method for each operation.

Project 4 – Console App (Client)

Contains the only default config needed to call Agatha services – and methods to call the service synchronously as well as asynchronously.

Running the sample

Just open it up in two different instances of VS – one for running your service layer – and the other for the client.

VS Instance 1 – In the first one, set the WCF service (AgathaHostSite) as the startup project. It should start up on a localhost – browse to localhost: port/Service.svc – and you should see a WcfRequestProcessor Service page (WcfRequestProcessor is the processor inside Agatha for handling WCF requests).

VS Instance 2 – Set the Console App (client) as the startup project. Start it to see your client – and initialize and invoke the service.

VS Instance 1 VS Instance 2 Started up WebService
agathaHostSiteStartup consoleappstartup agatha_service_page

 

Summary

For larger WCF projects, a layer such as Agatha becomes more than a convenience. Apart from saving tons of maintenance, it provides cleaner, fine grained operations.  These operations utilize a base RequestHandler class that contains a Handle operation. This operation is all you need to override for each of your custom service operations.

With IoC support, you no longer have to worry about initializing services (on the service layer or the client). With a single endpoint, you no longer have to worry about large XML web.configs. 

Source Code Download

The post Agatha–Getting Started–First Application appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]> https://www.anujvarma.com/agathagetting-startedfirst-application/feed/ 1 The Publish Subscribe Pattern in C# and some gotchas https://www.anujvarma.com/the-publish-subscribe-pattern-in-c-and-some-gotchas/ https://www.anujvarma.com/the-publish-subscribe-pattern-in-c-and-some-gotchas/#comments Wed, 17 Apr 2013 19:48:50 +0000 http://www.anujvarma.com/?p=1440 This post does three things: Provides a complete implementation of the publish subscribe pattern in C#. Highlights 4 potential issues that are inherent to ANY publish subscribe implementation – including […]

The post The Publish Subscribe Pattern in C# and some gotchas appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);}

This post does three things:

  1. Provides a complete implementation of the publish subscribe pattern in C#.
  2. Highlights 4 potential issues that are inherent to ANY publish subscribe implementation – including the one provided here.
  3. Provides original, tested workarounds for each of the 4 issues (source code included).

As far as the author is aware, this is the only publish subscribe implementation that provides these workarounds – making it immune from the common issues of badly behaved subscribers, race conditions and subscribers that fail to unsubscribe. 

UPDATE: With the introduction of two new interfaces (IObserver and IObservable) in .NET 4.0, there is a cleaner way to implement the Publish Subscribe pattern in C# .NET. However, the ‘gotchas’ listed here still apply. Even with the new interfaces, one still needs to worry about things such as ‘unsubscribing from the publisher’, ‘badly behaved subscribers’ and ‘new subscribers added while publishing is in progress’.

DELEGATES and EVENTS way OF IMPLEMENTING PUBLISH SUBSCRIBE in C#

 

Introduction : Events , combined with delegates in C#  make it possible to implement a simple publisher – subscriber pattern. If you are unfamiliar with delegates, read this post first.

There are three main players in any Publish Subscribe pattern implementation:

  1. The Event : The example below revolves around the ‘payday’ event – which is called PayrollArrived.
  2. The Publisher : The event is published by the Employer class (the Employer announces the payday when it arrives).
  3. The Subscriber : Each Employee (i.e. each instance of the Employee class) listens for the event – and is hence a subscriber to the PayrollArrived event.

 

The Event

Events provide a way to signal a change of state to whoever is ‘subscribed’ to that event. The arrival of the first of every month may be the event for publishing a new issue of a magazine. The subscribers would be everyone who has a paid subscription to the magazine – and the publisher would be the magazine publisher.

The arrival of the 15th of every month may be a payroll event for a company. The subscribers would be all employees who get paid on the payroll date.  The publisher would be the company itself that pays the employees on payroll day. The example code in this post deals with the latter event – a payroll event with an Employer (Publisher) and multiple Employees(Subscribers). 

// For events to be treated as 'fields', they need to be of type 'delegate'.

// First, define the delegate type for the event 

   public delegate void PayrollArrivedHandler(object sender, PublisherEventArgs e);

 

// public event declaration, a 'delegate' type for the event must be declared first

   public event PayrollArrivedHandler PayrollArrived;

The Publisher (Employer)

public class EmployerPublisher 

{

    LinkedList<Employee> _listSubscribers = new LinkedList<Employee>();

    public LinkedList<Employee> ListSubscribers

    {

        get { return _listSubscribers; }

        set { _listSubscribers = value; }

    }

 

    // For events to be treated as 'fields', they need to be of type 'delegate'.

    // First, define the delegate type for the event 

    public delegate void PayrollArrivedHandler(object sender, PublisherEventArgs e);

 

    // public event declaration, a 'delegate' type for the event must be declared first

    public event PayrollArrivedHandler PayrollArrived;

  

    // add new subscriber

    public void AddSubscriber(Employee em)

    {

        // Add new subscriber to the TOP of the linked list - this way it will not interfere with the notification in progress

        this.ListSubscribers.AddFirst(em);

 

        // Subscribe the new subscriber to the event.

        // The coupling between the publisher publishing and the subscriber subscribing is via the common delegate

        this.PayrollArrived += em.OnPayrollArrival;

    }

 

    // This event firing is synchronous - i.e. the publisher instance is tied down until the subscriber finishes processing OnPayrollArrival

    public void FireEvent(DateTime dayToFireEvent)

    {

        PublisherEventArgs args = new PublisherEventArgs();

        args.DateToFireEvent = dayToFireEvent;

 

        if (PayrollArrived != null)

            PayrollArrived(this, args);

    }

 

    // This is an asynchronous version of the same event-firing - just fire it - 

    // and do not CARE about how long the subscriber takes - since subscriber processing is on a different thread.

    // This works around the 'Badly behaved subscriber - Gotcha 1'.

    public void FireEventAsynchronous(DateTime dayToFireEvent)

    {

        if (PayrollArrived != null)

        {

            PublisherEventArgs args = new PublisherEventArgs();

            // We have more than one subscriber - employee 1 and empoyee 2. Each one subscribes via its own delegate. 

            // so - we need to loop over all the delegates

 

            Delegate[] delegates = PayrollArrived.GetInvocationList();

            foreach (Delegate del in delegates)

            {

                PayrollArrivedHandler handler = (PayrollArrivedHandler) del;

                handler.BeginInvoke(this, args, null, null);

            }

        }

    }

 

    public void RemoveSubscriber(Employee em)

    {

        this.PayrollArrived -= em.OnPayrollArrival;

    }

}

The Subscriber (Employee)

// Subscriber class – Employee – interested in knowing when the PayrollArrived event occurs

public class Employee 

{

   private string _name;

 

   public string Name

   {

       get { return _name; }

       set { _name = value; }

   }

 

   public Employee(string name)

   {

       this.Name = name;

   }

 

   public void OnPayrollArrival(object sender, PublisherEventArgs args)

   {

       DateTime dateToday = args.DateToFireEvent.Date;

 

       // Round up some friends and go spend the money!

       Console.WriteLine(this.Name + " was notified. Today is payday - date :" + dateToday);

   }

}

Most implementations out there have just the code above. They do not account for various things that can go wrong with a simple publish subscribe implementation.

 

What can go wrong? (The 4 main potential issues with any publish-subscribe implementation)

 

Gotcha 1 – The badly behaved subscriber

One rotten apple – blocks the others. When multiple subscribers are present – what if one of the subscribers blocks the publisher so that it is effectively not available to other subscribers?  This can easily occur if any one of the subscribers decide to do something lengthy in its event handler. How do we prevent such an occurrence?

Gotcha 2 – New Subscriber while notification is in progress

What if a subscriber is added while notification is in progress? Supposing the list of subscribers is being notified – and a new subscriber happens to come along (this is not a rare event – especially if any one of the subscribers happens to contain time-consuming code as in Gotcha 1) . What happens to the new subscriber? Does it get dropped? Do we add it? If so – where and when do we add it?

Gotcha 3 – Subscribers that fail to unsubscribe

A  good practice in .NET eventing is to ensure that all subscribers eventually unsubscribe from their events – once they are done handling it. Failure to do so leads to potential memory leaks.  This is actually one of the more common sources of memory leaks in .NET applications.

Gotcha 4 – Race conditions in the .NET framework

Race conditions in the .NET eventing framework – leading to inconsistent handling of events.

Workarounds for each of the Gotchas

 

Gotcha 1 Workaround 

The badly-behaved subscriber problem is best solved by working under the assumption that all subscribers will be badly behaved. So what is a publisher to do? One solution is to launch each notification on a new thread – that way even if a subscriber is badly behaved – it does not tie down the notification of other subscribers. Since the CLR in .NET provides a ready-made thread-pool, this is a seemingly simple solution. All one needs to do is use the built in support for asynchronous delegates (the event defined in the publisher class is really just a delegate – see sample below).

// This is an asynchronous version of the same event-firing - just fire it - 

// and do not CARE about how long the subscriber takes - since subscriber processing is on a different thread.

// This works around the 'Badly behaved subscriber - Gotcha 1'.

public void FireEventAsynchronous(DateTime dayToFireEvent)

{

    if (PayrollArrived != null)

    {

        PublisherEventArgs args = new PublisherEventArgs();

        // We have more than one subscriber - employee 1 and empoyee 2. Each one subscribes via its own delegate. 

        // so - we need to loop over all the delegates

        Delegate[] delegates = PayrollArrived.GetInvocationList();

        foreach (Delegate del in delegates)

        {

            PayrollArrivedHandler handler = (PayrollArrivedHandler) del;

            handler.BeginInvoke(this, args, null, null);

        }

    }

}

We are almost there. The only problem with the above code is a C# restriction – if you want to call BeginInvoke, your delegate (our event) can only have one target. We already have two targets (employee1.OnPayrollArrival and employee2.OnPayrollArrival) – so what do we do? Just loop over all the targets of our delegate – and call BeginInvoke on them one at a time. That should work around the original problem.

Gotcha 1 (Badly behaved subscribers) Workaround Summary

The badly-behaved subscriber problem is essentially addressed by launching each subscriber on a separate thread (and letting the subscribers stay badly behaved). We just don’t care – we’ve still managed to notify all the subscribers successfully.

Gotcha 2 (A subscriber is added while notification is in progress) Workaround

This is a slightly trickier problem to solve. We still want to allow the new subscriber to add itself – but we do not want to interfere with the current notification process. This solution is borrowed from Holub on Patterns – and works well in our scenario as well. The basic idea is that instead of having just ANY collection of subscribers – use a linked list to store subscribers.

Notification of the list of subscribers boils down to traversing the linked lists one node at a time. Say you are on some intermediate node – and a new subscriber arrives. Simply add the new subscriber (as a node) to the head of the list!

This way – it doesn’t interfere with the existing notification process – and is successfully added to the list of subscribers whenever the next notification comes around.

 

LinkedList<Employee> _listSubscribers = new LinkedList<Employee>();

public LinkedList<Employee> ListSubscribers

{

    get { return _listSubscribers; }

    set { _listSubscribers = value; }

}

// add new subscriber

   public void AddSubscriber(Employee em)

   {

       // Add new subscriber to the TOP of the linked list - this way it will not interfere with the notification in progress

       this.ListSubscribers.AddFirst(em);

Gotcha 2  Workaround Summary

Adding new subscribers while notification is in progress – is solved by ensuring that any new subscribers are added to the head of a linked list (containing all the subscribers)

Gotcha 3: Subscribers that fail to unsubscribe

The publisher holds a reference to every subscriber that has subscribed to its events. 2 subscribers – 2 references – 100 subscribers – 100 references. Unless each and every individual subscriber specifically unsubscribes after handling the event, the publisher does not release the reference to that subscriber. This leads to objects hanging around on the managed heap for longer than they are needed.

To work around this, simply ensure that a RemoveSubscriber method is available that can be called ON each subscriber (by the publisher) when it is done with the subscriber.

public void RemoveSubscriber(Employee em)

{

     this.PayrollArrived -= em.OnPayrollArrival;

}

Gotcha 3 Workaround Summary

Ensure that subscribers always unsubscribe from subscribed events when they are done. A simple RemoveSubscriber method as shown above can help accomplish this.

Gotcha 4 : Race Condition in the .NET eventing framework

This is not a publish-subscribe problem – but more an ‘eventing’ problem in the .NET framework. This ends up being a publish-subscribe problem nevertheless.

// initialize to empty delegate to avoid Gotcha 4 - race condition      

 public event PayrollArrivedHandler PayrollArrived = delegate {} ;

Gotcha 4 Workaround Summary

A simple workaround is to ensure that the event is always initialized to an empty delegate – this way it will never be null.

public event PayrollArrivedHandler PayrollArrived = delegate {} ;

 

Summary

The publish subscribe pattern is one of the most ubiquitous patterns in use today. Events and delegates in c# make it relatively simple to implement the pattern with a few lines of code. However, this implementation is prone to performance issues and potential bugs – if certain conditions are not handled up front.

With the 4 workarounds described in this post, the publish subscribe implementation (in C#) is as close to unbreakable as possible. Subscribers can continue to be long running , poorly behaved. Race conditions can try and cause unanticipated interjections. The simple workarounds in the sample code will handle these conditions.

These problems are especially noticeable when your event has a LARGE number of subscribers.

Full Source Code

Download Full Solution with the workarounds 

References

The post The Publish Subscribe Pattern in C# and some gotchas appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/the-publish-subscribe-pattern-in-c-and-some-gotchas/feed/ 5
A flexible service oriented architecture that handles multiple platforms (multiple devices, multiple databases…) https://www.anujvarma.com/a-flexible-service-oriented-architecture-that-handles-multiple-platforms-multiple-devices-multiple-databases/ https://www.anujvarma.com/a-flexible-service-oriented-architecture-that-handles-multiple-platforms-multiple-devices-multiple-databases/#respond Tue, 24 Apr 2012 18:57:15 +0000 http://www.anujvarma.com/a-flexible-service-oriented-architecture-that-handles-multiple-platforms-multiple-devices-multiple-databases/ The Problem Statement Imagine that you have just built a sophisticated application to work against a SQL Server database. You followed a best-practices approach and separated out your presentation, business […]

The post A flexible service oriented architecture that handles multiple platforms (multiple devices, multiple databases…) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
The Problem Statement

Imagine that you have just built a sophisticated application to work against a SQL Server database. You followed a best-practices approach and separated out your presentation, business logic and data access layer. Your application is service oriented – and exposes a set of services to the outside world. For e.g. – your application offers an Account Service and a Security Service for consumption by the outside world.

  1. Now – you are told that this application needs to work against not just SQL Server – but Oracle as well.
  2. However, the services (AccountService, SecurityService) – will be somewhat different for the Oracle version. 
  3. While the services may be different, a lot of the functionality between the platforms will be similar.
  4. In addition, your design must be flexible (extensible). If more database platforms were added down the road – or more services to go along with the AccountService and the SecurityServices, the design should accommodate these with minimal changes.

This can be summarized as supporting multiple services for multiple platforms (these platforms do not have to be multiple databases – can be multiple OSes, multiple device platforms –e.g. Mobile and Desktop).   One of the key issues that this design presents is that of code commonality –  and code differentiation. Some of the code for the multiple platforms may be common to both the platforms. Example – when the AccountService creates an Account, there may be exception handling code that is common to both Oracle and SqlServer. In addition – a good deal of code would be completely unique to each platform – so – a SQLServer account creation would use SQLServer authentication whereas an Oracle account creation would use Oracle specific authentication.

This article presents an architecture to solve both of the problems above (keeping common code as well as differentiation platform specific code) – and provides a full sample implementation. This implementation can be used for various problems that require accommodating multiple services and multiple platforms. The possibilities are limitless – and I have used this on at least 2 projects successfully.  It allows for extensibility by allowing more services to be added – as well as more platforms to be added down the road.

Starting Point – Make it simple for the client

What would a sample client need to do to invoke a sample platform-specific service ? Say – a client wanted to use the AccountService specific to SqlServer. The snippet below shows everything that a client should need to do – get a handle to the SqlServer factory. This factory is responsible for all SqlServer specific services – so getting an AccountService back from this factory should be as simple as a GetService call. The snippet below shows everything that a client should need to do.

Code Snippet
  1.  
  2. ServiceFactory.SqlServerServiceFactory sqlFactory = new ServiceFactory.SqlServerServiceFactory();
  3. IAccountService acctService = sqlFactory.GetService<IAccountService>();

An Introduction to the overall architecture

To model the various services (AccountService, SecurityService…), we notice firstly that these services are unrelated to each other. A prospective implementation could implement both the AccountService and the SecurityService.  This leads us to explore an interface based approach for the set of services.

Services by Feature (Account, Security) Architecture – An Interface Based Approach

Code Snippet
  1. interface IAccountService
  2.   {
  3.       void CreateAccount();
  4.   }

 

Code Snippet
  1. interface ISecurityService
  2.     {
  3.         void AuthenticateUser();
  4.     }

Services By Platform (SQLServer, Oracle…) Architecture – An Inheritance Based Approach

For the platform differentiation, we note that some of the code may be common to both platforms – for e.g. – error handling and exception logging from the AccountService would need to be identical for both Oracle and SqlServer. We use an inheritance based approach – which allows us to use a Template pattern. The template pattern would provide a template method – that consists of a) Common Code b) Platform Specific Code

Code Snippet
  1. public virtual void CreateAccount()
  2. {
  3.  
  4.     //  common code – example – Initialize
  5.     Console.WriteLine("Account Service: Common Initialization Code");
  6.  
  7.     // Platform specific code
  8.     SomePlatformSpecificOperation();
  9.  
  10.     // common code again – example – cleanup()…
  11.     Console.WriteLine("Account Service: Common Cleanup Code");
  12.  
  13. }
  14.  
  15. protected virtual void SomePlatformSpecificOperation()
  16. {
  17.     Console.WriteLine("Some BASE operation that is common to both ORACLE and SQLServer. This can be over-riddent in the child classes for PLATFORM speficic functionality");
  18. }

The Overall Architecture – using Inheritance for Platform Variation – and interfaces for services

services_architecture_object_model_thumb

 

The Service Factory

The only other component (apart from the interface based services and the inheritance based platforms) that we need is a service factory – one that will return the appropriate feature service (e.g. Account Service) – along with the appropriate platform (e.g. SqlServerAccountService).

Code Snippet
  1. interface IServiceFactory
  2.     {
  3.        T GetService<T>();
  4.     }

A simple dictionary is used to store the list of services (AccountService, SecurityService…) – and a lookup method is provided as shown below:

Code Snippet
  1. private IDictionary<string, object> allservices = new Dictionary<string, object>();
  2.  
  3. public T GetService<T>()
  4. {
  5.     object service = null;
  6.     T returnedService = (T)service;
  7.     string serviceName = typeof(T).FullName;
  8.     if (allservices.TryGetValue(serviceName, out service))
  9.     {
  10.         returnedService = (T)service;
  11.     }
  12.  
  13.     return returnedService;
  14.  
  15. }

Summary

Almost every app today follows a service oriented architecture which exposes multiple services. If our app was limited to just that, the above interface based approach coupled with our Service Factory (to return a specific service) would be all that is needed. However, today’s services are not just feature based – but also tend to support multiple platforms. These multiple platforms could be multiple databases (e.g. SQLServer and Oracle on the backend), multiple devices (e.g. Desktop and Mobile), multiple OSes etc.

This post provides a full object oriented implementation that supports multiple platforms along with multiple services (features). The multiple services were modeled using interfaces. Then, to account for the different platform implementations of each service, we defined an inheritance hierarchy – coupled with a template pattern to handle code commonality between the different platforms.

  This proves to be an elegant solution for a common, real-world problem in Object Oriented projects. There are a multitude of possible applications of the above architecture. 

Perhaps the greatest strength of the above architecture is the extensibility it provides. One can add new database platforms and new services down the road – with ease and minimal code changes.

NOTE: Ideally, you would want to design a Data Access Layer that was agnostic of the underlying database. This layer would generate all your SQL statements (CRUD) without caring about what the underlying database platform was. Such a database agnostic data access layer is described in an earlier post here.

Full Solution Download

Services_By_Platform_Architecture Download Solution

The post A flexible service oriented architecture that handles multiple platforms (multiple devices, multiple databases…) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/a-flexible-service-oriented-architecture-that-handles-multiple-platforms-multiple-devices-multiple-databases/feed/ 0
Abstract Factory in C# – Equally useful for manufacturing operations (services) and products https://www.anujvarma.com/abstract-factory-equally-useful-for-manufacturing-operations-services-and-products/ https://www.anujvarma.com/abstract-factory-equally-useful-for-manufacturing-operations-services-and-products/#respond Wed, 21 Sep 2011 22:13:26 +0000 http://www.anujvarma.com/abstract-factory-equally-useful-for-manufacturing-operations-services-and-products/ This article assumes some familiarity with the Factory pattern. The factory concept is equally useful for creating products (ProductFactory) or for creating services (ServiceFactory). A good way to start is […]

The post Abstract Factory in C# – Equally useful for manufacturing operations (services) and products appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
This article assumes some familiarity with the Factory pattern. The factory concept is equally useful for creating products (ProductFactory) or for creating services (ServiceFactory). A good way to start is to look at what the client really needs from the factory.

Product Factory Example – Client code

 // Create an instance of the concrete factory.
 // This is the only concrete class that the client needs to know about.
 // Everything else needed by the client remains abstract
AbstractProductFactory absProdFactory = new ConcreteProductFactory();
AbstractProduct absProductA;
AbstractProduct absProductB;

absProductA = absProdFactory.CreateProductA();
absProductB = absProdFactory.CreateProductB();
string pA1 = absProductA.ProductProperty1();
string pA2 = absProductA.ProductProperty2();
string pB1 = absProductB.ProductProperty1();
string pB2 = absProductB.ProductProperty2();

 

Service Factory Example – Client code

static void Main(string[] args)
{
// Create an instance of the concrete factory – this is the only concrete class that the client needs to know about.
// Everything else needed by the client remains abstract
          AbstractFactory absFactory = new ConcreteFactory();
          AbstractService absServiceA;
          AbstractService absServiceB;

          absServiceA = absFactory.CreateServiceA();
          absServiceB = absFactory.CreateServiceB();

          string sA1 = absServiceA.serviceOperation1();
          string sA2 = absServiceA.serviceOperation2();

          string sB1 = absServiceB.serviceOperation1();
          string sB2 = absServiceB.serviceOperation2();

 }

The post Abstract Factory in C# – Equally useful for manufacturing operations (services) and products appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/abstract-factory-equally-useful-for-manufacturing-operations-services-and-products/feed/ 0
WCF and Publish Subscribe–A Full Example: Running the Client (Subscriber) https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-running-the-client-subscriber/ https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-running-the-client-subscriber/#comments Thu, 28 Jul 2011 19:58:47 +0000 http://www.anujvarma.com/wcf-and-publish-subscribea-full-example-running-the-client-subscriber/ Now that all the pieces are in place, we are ready to run our client program.  The first error I encountered was: AddressAccessDeniedException: HTTP could not register URL http://+:8080/ Step […]

The post WCF and Publish Subscribe–A Full Example: Running the Client (Subscriber) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
Now that all the pieces are in place, we are ready to run our client program.  The first error I encountered was:

AddressAccessDeniedException: HTTP could not register URL http://+:8080/

Step 1 – On running the Subscriber project, you may get an AddressAccessDenied exception (especially if you are on Windows Vista). To work around this error, launch a command prompt as administrator (right click and Run As Admin). In the command prompt, type :

netsh http add urlacl url=http://+:26836/ user=DOMAIN\UserName (do you need to lookup your username or your domain name ?).

Step 2 – What I needed was to provide local access to the address on which the client was running (the callback address). A tool called HttpNamespaceManager allowed me to grant that access to the http address+port that I needed. (See http://blogs.msdn.com/b/paulwh/archive/2007/05/04/addressaccessdeniedexception-http-could-not-register-url-http-8080.aspx for details). A quick summary of how to work around this error is given below:

1. Copy the http namespace from your DOS prompt.

dos_copy_url

2. Launch HttpNamespaces exe – Click Add – Paste the copied URL into the URL textbox that appears.

add_http_namespace

3. Grant access to the following USER GROUPS – USERS and LOCAL SERVICE. Once you add these groups, select them and check the ‘GenericExecute’ box as shown below.

USERS_group   execute_perms_users_group

Summary

Once you get past the Unhandled Exception: System.ServiceModel.AddressAccessDeniedException (using the steps above), you should be able to run the Subscriber console app (make sure you run the service first by starting the MagazineService project as shown below. You CAN run both from the same Visual Studio Solution Explorer).

launch_service

 

download full source codeWCFPublishSubscribe.zip

The post WCF and Publish Subscribe–A Full Example: Running the Client (Subscriber) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-running-the-client-subscriber/feed/ 11
WCF and Publish Subscribe–A Full Example: Client Code https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-client-code/ https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-client-code/#comments Thu, 28 Jul 2011 19:55:37 +0000 http://www.anujvarma.com/wcf-and-publish-subscribea-full-example-client-code/ The subscriber needs to know about the service. We will use svcutil.exe to generate the proxy class for the subscribers to use. Step 1 : Ensure Service Loads Ok Use […]

The post WCF and Publish Subscribe–A Full Example: Client Code appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
The subscriber needs to know about the service. We will use svcutil.exe to generate the proxy class for the subscribers to use.

Step 1 : Ensure Service Loads Ok

  1. Use CRL F5 to start the Magazine service  – it should start running on a local port such as http://localhost:26836/. Click on MagazineService.svc to ensure that it is setup right (you will encounter errors if something was incorrect). The first error I encountered was related to the http binding. The default http binding is ‘BasicHttpBinding’  – and BasicHttpBinding does not support sessions (need wsDualHttpBinding for that) service_error_1 
  2. Inserting the following inside the <system.serviceModel> element fixed the issue                           <protocolMapping> <add scheme=httpbinding=wsDualHttpBinding/> </protocolMapping>
  3. Once the service fires up without errors (e.g. http://localhost:26836/MagazineService.svc), we are ready to generate our proxy.

Step 2: Generate the proxy

  1. Add a reference to System.ServiceModel in your Subscriber (client) project.
  2. On the Start menu click All Programs, and then click Visual Studio 2010. Click Visual Studio Tools and then click Visual Studio 2010 Command Prompt (you would need to ‘Run As Administrator’ if you are not logged on as the administrator).
  3. c:\Program Files\Microsoft Visual Studio 10.0\VC>svcutil /language:cs /out:generatedProxy.cs /config:app.config http://localhost:26836/MagazineService.svc
  4. Copy over the two files (generatedProxy.cs and app.config) to the folder containing the client project (subscriber project) – and ‘Add Existing Items’ to the project. Your solution should look something like this at this point.                                                                                                                                                                                                                                                                                                                                                                                    solution_explorer

Step 3: Client (Subscriber) Code

Now that we are done with the plumbing, we are ready to code our client.  Our client is just a subscriber who wants to be notified (on its callback method) whenever a new issue is available.

  1. A client class : Note that we already have a client class provided by the proxy. This is called  MagazineServiceClient.
public partial class MagazineServiceClient

     2.   A callback interface: The interface IMagazineServiceCallback is also available to us through our generated proxy.

Our client is just a subscriber who wants to be notified (on its callback method) whenever a new issue is available.

Here is the complete client code:

//The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

//Client implementation code.

 

class Subscriber : IMagazineServiceCallback

{

        static void Main(string[] args)

        {

            // always create an instance context to associate the service with            

            InstanceContext siteHostContext = new InstanceContext(null, new Subscriber());

 

            MagazineServiceClient myClient = new MagazineServiceClient(siteHostContext);

 

            // create a unique callback address (if you want multiple subscribers to run on the same machine)

            WSDualHttpBinding binding = (WSDualHttpBinding)myClient.Endpoint.Binding;

            string uniqueCallbackAddress = binding.ClientBaseAddress.AbsoluteUri;

 

            // make it unique - append a GUID

            uniqueCallbackAddress += Guid.NewGuid().ToString();

            //uniqueCallbackAddress += 9;

            binding.ClientBaseAddress = new Uri(uniqueCallbackAddress);

 

            // Subcribe

            Console.WriteLine("subscribing...");

            myClient.Subscribe();

 

            Console.WriteLine();

            Console.WriteLine("Press ENTER to unsubscribe");

            Console.ReadLine();

 

            Console.WriteLine("unsubscribing...");

            myClient.Unsubscribe();

 

            // Closes the underlying http connection

            myClient.Close();            

        }

 

        public void MessageReceived(string linkToNewIssue, string issueNumber, DateTime publishDate)

        {

            Console.WriteLine("MessageRecei(item{0}, item{1}, item{2}", linkToNewIssue, issueNumber, publishDate);

        }

}

At this point, your project is complete. You have a working Service and a working client. See the next post – Running your client (adding a new subscriber and getting notified of new published events).

The post WCF and Publish Subscribe–A Full Example: Client Code appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-client-code/feed/ 1
WCF and Publish Subscribe–A Full Example: The Event Generator https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-the-event-generator/ https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-the-event-generator/#comments Thu, 28 Jul 2011 16:09:16 +0000 http://www.anujvarma.com/wcf-and-publish-subscribea-full-example-the-event-generator/ The purpose of the Event Generator code is to publish events (New Magazine Issue Available)  that subscribers will get notified about. Add a new Console App (Add New Project) to […]

The post WCF and Publish Subscribe–A Full Example: The Event Generator appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
The purpose of the Event Generator code is to publish events (New Magazine Issue Available)  that subscribers will get notified about.

  1. Add a new Console App (Add New Project) to the WCFPublishSubscribe solutionCall it EventGenerator.
  2. Copy over the app.config and the generatedProxy.cs to this new project.
  3. Publishing an event is as simple as invoking the Publish method (PublishMagazine) on the client (proxy class)
myClient.PublishMagazine("http://www.anujvarma.com", "Vol1: Issue1", System.DateTime.Now);

class EventGenerator: IMagazineServiceCallback

    {

        static void Main(string[] args)

        {

            // always create an instance context to associate the service with            

            InstanceContext siteHostContext = new InstanceContext(null, new EventGenerator());

            MagazineServiceClient myClient = new MagazineServiceClient(siteHostContext);

 

            Console.WriteLine("Publishing New Issue(http://www.anujvarma.com, Vol1: Number1, )");

            myClient.PublishMagazine("http://www.anujvarma.com", "Vol1: Issue1", System.DateTime.Now);

 

            Console.WriteLine();

            Console.WriteLine("Press ENTER to stop publishing events");

            Console.ReadLine();

 

            //Closing the client gracefully closes the connection and cleans up resources

            myClient.Close();

        }

 

        public void MessageReceived(string linkToNewIssue, string issueNumber, DateTime publishDate)

        {

            Console.WriteLine("MessageReceived(item{0}, item{1}, item{2}", linkToNewIssue, issueNumber, publishDate);

        }

    }

The post WCF and Publish Subscribe–A Full Example: The Event Generator appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/wcf-and-publish-subscribea-full-example-the-event-generator/feed/ 1
WCF Publish Subscribe– A Full Example: The Service Side Part 2 (Implementation) https://www.anujvarma.com/wcf-publish-subscribe-a-full-example-the-service-side-part-2-implementation/ https://www.anujvarma.com/wcf-publish-subscribe-a-full-example-the-service-side-part-2-implementation/#comments Thu, 28 Jul 2011 16:02:11 +0000 http://www.anujvarma.com/wcf-publish-subscribe-a-full-example-the-service-side-part-2-implementation/ Our implementation is based on .NET events (for a non-events based implementation, check out the New IObserver IObservable interfaces in C# 4.0). The idea of publishing goes hand-in-hand with ‘raising […]

The post WCF Publish Subscribe– A Full Example: The Service Side Part 2 (Implementation) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
Our implementation is based on .NET events (for a non-events based implementation, check out the New IObserver IObservable interfaces in C# 4.0). The idea of publishing goes hand-in-hand with ‘raising an event’  – and the idea of subscribers goes hand-in-hand with consuming an event.

Our event based implementation thus consists of:

  1. Defining an event
  2. Defining an  event handler (all the handler will do is notify the various subscribers)
  3. Implement the Subscribe method
  4. Implement the Unsubscribe method
  5. Implement the PublishMagazine method
public class NewIssueAvailableEventArgs : EventArgs

{

    public string hyperlinkURL;

    public string issueNumber;

    public DateTime datePublished;

}

 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]

public class MagazineService : IMagazineService

{

    public static event NewIssueAvailableHandler NewIssueAvailableEvent;

    public delegate void NewIssueAvailableHandler(object sender, NewIssueAvailableEventArgs e);

 

    // instance of eventhandler

    NewIssueAvailableHandler newIssueHandler;

 

    // Callback to individual clients using the ClientContract

    IClientContract callback = null;

 

    public void PublishMagazine(string hyperLinkToIssue, string issueNumber, DateTime datePublished)

    {

        NewIssueAvailableEventArgs eargs = new NewIssueAvailableEventArgs();

        eargs.hyperlinkURL = hyperLinkToIssue;

        eargs.issueNumber = issueNumber;

        eargs.datePublished = datePublished;

 

        // fire the event

        NewIssueAvailableEvent(this, eargs);

    }

 

    public void Subscribe()

    {

        callback = OperationContext.Current.GetCallbackChannel<IClientContract>();

        // this is the handler that we will 'unsubscribe' from later

        newIssueHandler = new NewIssueAvailableHandler(MagazineService_NewIssueAvailableEvent);

        NewIssueAvailableEvent += newIssueHandler;

    }

 

    public void Unsubscribe()

    {

        NewIssueAvailableEvent -= newIssueHandler;

    }

 

    public void MagazineService_NewIssueAvailableEvent(object sender, NewIssueAvailableEventArgs e)

    {

        callback.MessageReceived(e.hyperlinkURL, e.issueNumber, e.datePublished);

    }

}

The post WCF Publish Subscribe– A Full Example: The Service Side Part 2 (Implementation) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/wcf-publish-subscribe-a-full-example-the-service-side-part-2-implementation/feed/ 8
WCF Publish Subscribe–A Full Example – The Service Side Part 1 (Interface) https://www.anujvarma.com/wcf-publish-subscribea-full-example-the-service-side-part-1-interface/ https://www.anujvarma.com/wcf-publish-subscribea-full-example-the-service-side-part-1-interface/#comments Thu, 28 Jul 2011 15:59:14 +0000 http://www.anujvarma.com/wcf-publish-subscribea-full-example-the-service-side-part-1-interface/ The Service code consists of an Interface (IMagazineService) and its implementation (MagazineService). The Interface defines all the capabilities of the service. What do we really want from a Publisher service? […]

The post WCF Publish Subscribe–A Full Example – The Service Side Part 1 (Interface) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
The Service code consists of an Interface (IMagazineService) and its implementation (MagazineService).

The Interface defines all the capabilities of the service. What do we really want from a Publisher service?

  1. A Publish method (called PublishMagazine)
  2. A Subscribe method (to allow clients to subscribe to the service)
  3. An Unsubscribe method (to allow clients to unsubscribe from the service)

Those are the three main things we need from our Publisher service. As long as all we need is the Publisher to get in touch with multiple subscribers, we are all set.

However, we also need a way to notify individual clients (subscribers) who have subscribed to our service. 

This can be handled via a Callback method (called MessageReceived in our example). The Callback method is best made available as part of a separate interface (known as IClientContract).

public interface IClientContract

{

    [OperationContract(IsOneWay = true)]

    void MessageReceived(string hyperlinkToNewIssue, string issueNumber, DateTime datePublished);

}

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IClientContract))]

public interface IMagazineService

{

    [OperationContract(IsOneWay = false, IsInitiating = true)]

    void PublishMagazine(string hyperLinkToIssue, string issueNumber, DateTime datePublished);

    [OperationContract(IsOneWay = false, IsTerminating = true)]

    void Subscribe();

    [OperationContract(IsOneWay = false, IsTerminating = true)]

    void Unsubscribe();

 

}

 

public interface IClientContract

{

    [OperationContract(IsOneWay = true)]

    void MessageReceived(string hyperlinkToNewIssue, string issueNumber, DateTime datePublished);

}

The post WCF Publish Subscribe–A Full Example – The Service Side Part 1 (Interface) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/wcf-publish-subscribea-full-example-the-service-side-part-1-interface/feed/ 2