I am using WCF for data services only (ie internal to the application and very lean with no session state etc) to keep our web application scalable.
We need to provide some common properties for every service call that we are currently passing in all the time. Having single request objects for every call is not ideal as beyond these common properties, the rest are very varied and change quite frequently during development.
At the moment I'm considering using custom headers and the clientmessageinspector to do to set the values. Is this the simplest recommended approach for this scenario or is there a better approach?
More detail..
The red points below are where I'm unsure the right approach (or how to go about it).
What's being sent
The data being sent is simple set of ids (3 or 4 for userid, clientid etc) - all these ids have an impact on security and on performance (in some cases it determines what database to go to).
We will also be extending this to have more complex permissions - not needed for the windows workers.
The caller will be either a web application where these come off a session object, or a windows service worker where these are manually populated.
The Current Thinking
Ideally, getinstance on the caller's workflow would either populate these properties automatically with the session object or more manually with the windows service calls (different constructors?).
We would then ensure that these parameters are always available without any thought or without constant references throughout the code to construct the contract on each function that calls it. We currently have a lot of service calls (due to scale/complexity of app, not due to bad engineering :)), so as this extends for complex permissions it is becoming a bit difficult to enforce rules in a self-documenting way.
Conceptually, session is where you'd take care of this in the app, but the services are really just a data access layer (with view mapping, pageing and last call security from repository calls) so we don't need that sort of repitition or complexity, just the key identitiy & permission fields to include in queries.
The Problem
This feels very much like something we should be doing with headers on the calls as we always need these fields, but I'm a little unsure of where the set and get should sit in the lifecycle of the endpoint and the client interface. I'm also happy to be wrong about that.
In my experience using message insprectors can be quite tricky to initially set up and configure, and in my research there was no site that covered everything, I had to pick snippets from several different places and piece it all together.
You need to question what you are putting in the headers. Is it information that needs to be available to the method being called? If so then putting it in the headers is the wrong option, as each method will need to parse the info back out.
The sort of info that is ideal for this is custom authentication and/or user specific metadata related to the WCF call. In my case I had a WCF call initiated by an automated service which was relayed to further WCF end points, this was an ideal scenario to use message inspectors as I was able to add metadata to the headers at the relay points for consumption by the subsequent end point.
If youy are simply looking to package up some data that is common to each call, then I would include create a base data object that has the appropriate properties and then just extend that for the more specialised calls (the end point can ensure that common data is either present, or assume some default values if it isn't). For common data required by each end point using message inspectors is overkill and potentially not viable.
I have applied a similar architecture; basicly every client call needs to carry some information regarding which DB to be selected, an identifier etc. And in the server side, these parameters shall be processed automatically and stored in a dictionary.
I have created a generic proxy class to wrap client proxies, in order to add related headers to each service call. Every developer who needs to call a service, used this generic proxy class in their calls.
In the service side, I have implemented a DispatchMessageInspector
as an endpoint behavior, where data is extracted from request headers and stored in a dictionary. The dictionary is initialized inside an extension of OperationContext (IExtension<OperationContext>
) and is available during the request processing.
Note that the instance context mode of services are PerCall
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With