WCF Service Behavior to add an operation to my services - wcf

I'd like to create a service behavior which adds an extra service operation to my service. This way I can add the behavior to any of my services (existing and future) and my service will all be able to perform this extra service operation. (e.g. ping or returns some other service information)
I'm not sure what to do here to achieve what I want, What I've tried to do so far is to implement a service behavior which tries to modify the service description. Should I add an endpoint and then specify a new contract on that?
public class MyOperationBehavior : IServiceBehavior
{
void IServiceBehavior.ApplyDispatchBehavior(
ServiceDescription desc, ServiceHostBase host)
{
ServiceEndpointCollection sec = svcDesc.Endpoints;
ServiceEndpoint se = new ServiceEndpoint()
{
se.Address = "DoMyOperation";
se.Binding = "basicHttpBinding";
se.Contract = MyCustomContract;
}
}
}

One of the benefits of using services is that you are exposing a well-defined and fairly static set of operations to your consumers.
I'm not sure how being able to dynamically add service operations at runtime would benefit your consumers.
I would suggest that if you need to change your service contract on a per-consumer basis then it may indicate that your service composition is probably incorrect for the needs of your consumers.
Apologies this does not answer your question directly, and appreciate that re-work on the scale suggested may be outside current development scope.

I've found what I was looking for in this article on Dynamically adding methods to a WCF service without having to add it to each service contract.
But I also believe using WS-Discovery is a much better way of achieving what I want: exposing information about a service without having to touch the service contracts

Related

single WCF endpoint for all commands in Nservicebus

We are trying to build a Nservicebus service that can communicated with form and wpf based clients using WCF. I have read that you can inherit from WcfService.
like:
public class ThirdPartyWebSvc : WcfService<ThirdPartyCmd, ThirdPartyCmdResponse>
And then you simple create a endpoint in the app.config and you done like described here. but the problem is that i have to create a endpoint for every command.
I would like to have a single endpoint that excepts any command and returns its response.
public class ThirdPartyWebSvc : WcfService<ICommand, IMessage>
Can someone point me in the right direction? Using Nservicebus for client communication can't be done for us and i don't want to build a proxy like server unless thats the only way to do it.
Thanks
So from what I can gather, you want to expose a WCF service operation which consumers can call to polymorphically pass one of a number of possible commands to, and then have the service route that command to the correct NServiceBus endpoint which then handles the command.
Firstly, in order to achieve this you should forget about using the NserviceBus.WcfService base class, because to use this you must closely follow the guidance in the article you linked in your post.
Instead, you could:
design your service operation contract to accept polymorphic requests by using the ServiceKnownType attribute on your operation definition, adding all possible command types,
host the service using a regular System.ServiceModel.ServiceHost(), and then configure an NserviceBus.IBus in the startup of your hosted WCF service, and
define your UnicastBusConfig config section in your service config file by adding all the command types along with the recipient queue addresses
However, you now have the following drawbacks:
Because of the requirement to be able to pass in implementations of ICommand into the service, you will need to recompile your operation contract each time you need to add a new command type.
You will need to manage a large quantity of routing information in the config file, and if any of the recipient endpoints change, you will need to change your service config.
If your service has availability problems then no more messages to any of your NSB endpoints.
You will need to write code to handle what to do if you do not receive a response message from the NSB endpoints in a timely manner, and this logic may depend on the type of command sent.
I hope you are beginning to see how centralizing this functionality is not a great idea.
All the above problems would go away if you could get your clients to send commands to the bus in the standard way, but without msmq how can you do that?
Well, for a start you could look at using one of the other supported transports.
If none of these work for you and you have to use WCF hosted services, then you must follow the guidance in the linked article. This guidance is there to steer you in the correct direction - multiple WCF services sounds like a pain, until you try to centralize them into a single service - then the pain gets bigger, not less.

Web service coordination

We are creating a WCF infrastructure to allow other systems in the organization to consume our business logic. Some of this logic has to do with user authentication, so securing the services is of high concern. The transport layer is secured by certificates. I am more concerned with securing the business layer.
One of our clients calls these services in a certain sequence, in order to support a business process. What I would like to do is put in place some mechanism to verify that the sequence is indeed kept. The sequence can be disrupted by developer errors on the consuming side or by attackers trying to compromise the system. I do not want to put the logic of the process inside the services themselves, since this will couple them to this specific client`s process. I would like to put the logic for coordinating the different services in a separate layer, which will be client specific (or maybe something more generic to support any process?)
Can someone point me to specific patterns or resources which discuss this issue?
I have been searching Google for half a day, and I can`t seem to find any resource discussing this specific issue.
Most web services should be designed to be called independently, since there's no guarantee what order the caller will compose them.
That having been said, one way to encourage them to be called in order is to use a design akin to a Fluent Interface, in which Service A returns an object that is an input parameter to Service B.
[DataContract]
public class ServiceAResult
{
// ...
}
[DataContract]
public class ServiceBResult
{
// ...
}
[ServiceContract]
public interface IServiceA {
[OperationContract]
public ServiceAResult OperationA() {
// ...
}
}
[ServiceContract]
public interface IServiceB {
[OperationContract]
public ServiceBResult OperationB(ServiceAResult input) {
// ...
}
}
Here, the easiest way to create a ServiceAResult to pass to ServiceB.OperationB is to call ServiceA.OperationA.
I recommend you separate your concerns.
Have a web service whose operations are called in order to perform your business processes.
Have a second service which orchestrates your business processes and which calls the operations of the first service in the required order.
Do not make it the responsibility of the first service to ensure that the second service calls things in the correct order. The responsibility of the order of calls should belong to a different service.

Making Backward-Compatible WCF Services

TLDR: How do I create WCF services that are backward compatible -- that is, when I deploy a new version of the service on the server-side, all the clients on the older versions can still use the service.
I'm creating a web service that will allow the client applications to fetch a listing of plugins. I will at least have one operation like FindPlugins(string nameOrDescription) which will, on the server, do a search and return a list of objects.
Unfortunately, I cannot guarantee that my clients will all be updated with each new release of my service; nay, I am sure that many of them will be trailing the latest version, and will have old versions -- how old, I cannot be sure, but I know they will be old :)
If I create a new service operation, change the schema, or make some sort of breaking operation on the server side, I'm done. I need to engineer backward compatibility at all times.
Here's one example. Say I return a list of Plugins, each which has a name and description, and I deploy v0.1 of my service. Then, I add a download link, and deploy that as v0.2 of my service.
Some options which I see are:
Force clients to update to the latest service (not feasible)
Break the service for old clients (not feasible)
Append a version number to each operation and only consume the version-specific operations (eg. FindPluginsV1, FindPluginsV2) -- doesn't seem practical with multiple operations
Provide a new service with each new version -- doesn't seem practical
WCF is backwards-compatible by default.
The following MSDN link contains a list of all the possible changes of a WCF contract and describes their effect on old clients:
WCF Essentials: Versioning Strategies
Most importantly, the following operations will not cause old clients to break:
Service contracts (methods)
Adding method parameters: The default value will be used when called from old clients.
Removing methods parameters: The values sent by old clients will be ignored silently.
Adding new methods: Obviously, old clients won't call them, since they don't know them.
Data contracts (custom classes for passing data)
Adding non-required properties.
Removing non-required properties.
Thus, unless you mark the new DownloadLink field as IsRequired (default is false), your change should be fine.
If you look at this article http://blogs.msdn.com/b/craigmcmurtry/archive/2006/07/23/676104.aspx
The first example the guy gives will satisfy your requirements. It has the benefit that existing clients will not break, and you can add as many new service operations as you want this way.
[ServiceContract]
public interface IMyServiceContract
{
[OperationContract(IsOneWay=true)]
public void MyMethod(MyDataContract input);
}
[ServiceContract]
public interface IMyAugmentedServiceContract: IMyServiceContract
{
[OperationContract(IsOneWay=true)]
public void MyNewMethod(MyOtherDataContract input);
}
The change your service implementation:
public class MyOriginalServiceType: IAugmentedServiceContract { }

Utilizing multiple service contracts over the same WCF channel or session

I'm in the process of writing a duplex WCF service using NetTcpBinding, and I've run into an architecture question that I think I know the answer to, but hope that I'm wrong.
Our service is stateful, and we've selected NetTcpBinding with PerSession InstanceContextMode. For various reasons, this is something that we require. I'm trying to break up our larger interface (where large blocks of the operations would not apply to many clients) into multiple smaller interfaces with the operations logically grouped. While it's simple enough to have a single service implementation implement all of the contracts, I'm not sure if it's possible to have multiple service contracts share a single channel (or, more to my requirement, a single session), and I'd definitely need to be able to do that in order to make this work.
I could, of course, include everything on one contract and throw FaultExceptions when an invalid operation is performed, but I'd really like to be able to break these up and not even add an endpoint for inapplicable contracts. Is what I'm looking for possible?
TL;DR Version:
I need to be able to do this:
[ServiceContract]
public interface IServiceA
{
[OperationContract]
void Foo();
}
[ServiceContract]
public interface IServiceB
{
[OperationContract]
void Bar();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service : IServiceA, IServiceB
{
...
}
And be able to establish one session from the client to the service but use both IServiceA and IServiceB.
The default instance provider over a sessionful channel will give you an instance per connection in your case. You can however extend the instance provider to pick up an existing object from your own cache and return the same object.
How you correlate instances will be upto you using some special message header etc. The underlying channel/Connection will be different for each proxy and also use differnt buffers / concurrency models but you can allow service model to use the same instance.
http://msdn.microsoft.com/en-us/magazine/cc163590.aspx

WCF service calls includes same information in every call

I have a web service that will be consumed by some application (web site currently).
The calls are almost all specific to a certain client but still the same. So one call might be getAllFoo() but I would need some parameter to say from which client the Foo is.
It would become bothersome quickly if I just add a standard parameter to all calls so I was hoping to do it a little bit DRY and automatic. Something that would be included in all service calls.
Is IDispatchMessageInspector the right thing for me here? What kind of info could that include and can I access that info inside the methods?
Should I create some sort of attribute perhaps for the calls?
If anyone could point me towards a solution for this it would be great.
Edit
Another solution I'm thinking off.
Where the service call to a specific client happens on the consumer side, it will be known at instanceCreation so I could instance the ServiceClient with a known client.
Could I use this solution for the ClientBase<> extender somehow.
Let's say I'm serving Domain1 (let's call the client Domain to not confuse it with a serviceclient/consumer) I create a InformationProvider consumer side that has a ClientBase<IInformationService> field. I ensure that the DomainName (domain1) is set at construction so I could parhaps do the same thing when instancing the ClientBase<IInformationService> so It somehow let's the service know what domain I'm calling for.
I'm just still learning about WCF so I'm not sure how one would do this.
I can understand that you want to keep you solution simple and tidy, but ultimately - as you say yourself -
... I would need some parameter to say from which client...
The obvious and simplest solution is to include a client parameter on all your service calls where it is required. Surely there'll be service calls that don't require the client parameter, and in those cases you don't need to include the parameter.
You may be able to do something clever where a client identifier is passed discreetly under the covers, but beware of doing unnecessarily clever things. I would pass the client as a simple parameter because it is being used as a parameter. Two reasons come to mind:
if someone maintains your code they quickly understand what's going on.
if someone needs to use the service it is obvious how to use it.
A possible pattern:
Make sure you service instantiates per session. This means you'll have to use wsHttpBinding, netTcpBinding, or a custom binding as http does not support sessions.
Always call an initialization operation when each session is instantiated that sets the client id for that service.
Put this initialization operation inside a constructor for a proxy.
The steps involved would be something like this:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
private int clientId;
public void StartUp(int clientId)
{
this.clientId = clientId;
and then client side, assuming you use the generated proxy, wrap the client inside another proxy.
public class ExtendedClient : MyServiceClient
{
public ExtendedClient(int clientid) : base()
{
this.StartUp(clientid);
}
Now you should instantiate the ExtendedClient, it will create the channel and prime the service by delivering the client id.
I would personally prefer to simply send the client id for each service call, but if you are able to use a session-able binding then this should work.
Just some information on WCF for you. If you have a stateless service, then you'll need to include the client as a parameter in every service call. This does not mean you need to include the client everywhere throughout your code - you could, for example, retrieve it inside the ClientBase constructor. But you will need to add it to every OperationContract and all the service implementations.
The alternative is to have a stateful service - the instance that you first use will remain for you to reuse (except for timeouts / exceptions). In this case you can potentially send the client just once, and then the service will know about the client for subsequent calls. This is the pattern described above. It means that you cannot use http binding. I believe that by doing this you're only increasing the potential for problems in your application (stateful services, having to ensure the initialization operation completes, more service calls being made).