Pregunta

I need to have a service which would be called from my client project. The requirement is that I can change and release a service but after changing the service there should not be a need to rebuild the client. The example is, suppose I have service which helps s person reach the destination

[ServiceContract]
IDestinationHelper
{
  [OperationContract]
  void ReachDestination(string person);
}

class ReachedByTrain:IDetinationHelper
{
  void ReachDestination(string person)
  {
    //Help the person to reach destination
  }
}

Now the service is helping the person to reach the destination by train, in this case I will be calling the ReachedByTrain service from client, but suppose a requirement comes and I want the person to reach by Flight, in that case how should I proceed without changing or building the client. The functionality should be plugable and client should automatically detect it

class ReachedByFlight:IDetinationHelper
    {
      void ReachDestination(string person)
      {
        //Help the person to reach destination
      }
    }

Please provide any help or reference about how it can be done.

P.S There will be only one mode present to the client at a time. No matter if the client doesn't know about it.

¿Fue útil?

Solución

You have multiple ways to reach extensibility.

The interface is fixed in your client. Building code that handles a changing interface is hard and error prone. Don't do that.

So you will need to keep the interface intact and change the internal behaviour of your class.

In your example, your service could return a list of points as a route to the target and a string that notes the transportation mode. Now you can include all sort of transportation modes and return routes for them without changing the interface.

When you add a new possible transportation mode, the client must be notified so it can be presented to the user for example in a ComboBox. That means you need a method in your interface that returns all possible transportation modes. That way, your client can handle new ones without recompile. It can even handle it when you remove modes.

This way your client has a contract and the contract never changes. But your methods can return different things when you rebuild and redeploy your service.

Example:

This contract never changes:

[ServiceContract]
IDestinationHelper
{
  [OperationContract]
  IEnumerable<Waypoint> ReachDestination(string transportationMode);

  [OperationContract]
  IEnumerable<string> GetAvailabletransportationModes();
}

IDestinationHelperService : IDestinationHelper
{
  public IEnumerable<Waypoint> ReachDestination(string transportationMode)
  {
     // decide return value by transportation mode. Use a switch statement, dependency injection, IoC containers, whatever you want
  }

  public IEnumerable<string> GetAvailabletransportationModes()
  {
     // decide return value by getting all modes from wherever you decided upon above.
  }
}

Otros consejos

I think you need to have a [ServiceContract] with an [OperationContract] which would take "ModeOfTransport" as a parameter and has a routing logic to create an object of either ReachByTrain or ReachByPlane or ReachByAnything and would call it from within the [OperationContract]. From the client side you can call the [OperationContract] which has the routing logic with the appropriate parameter on hand.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top