Shape a WCF service by endpoint - wcf

I have 2 contracts (cA & cB) implemented by a single WCF service with 2 endpoints (epA & epB).
This is not for security purposes, but purely for reasons of clarity/organization, I'd like to only "see" ContractA's operations when I discover the service via endpointA; and likewise, only see ContractB's operations via endpointB.
I don't need to "protect" these operations per se. The scenario is such that any given client only needs one "side" of the service, never both (but, the operations themselves share resources, so it makes sense to have a single service rather than 2 services).
It seems that any given service basically gets 1 WSDL, ergo all operations are exposed to all endpoints. Is that the way it works, or is there a way to "shape" an endpoint by occluding operations not defined by the endpoints contract?

By default, you're right - one service implementation class gets one WSDL which contains all service methods (from all service contracts) that this service class implements.
There are no ways present (as far as I know) to "shape" the WSDL in any (easy) way - WCF does offer ways to get into the process of creating the WSDL (statically or dynamically), but those aren't for the faint of heart. It would be much easier for you to just split the implementation of the service contracts into two separate classes and then you'd have two separate services, separate WSDL's and all.

Marc is absolutelly right. I'm just adding why this happens in WCF. In WCF all metadata related functionality are based around service metadata behavior and mex endpoint. Both these features are defined on service level. So you can't take higher granuality (unless you write a lot of custom code) and specify metadata per endpoint.
WCF service (class) is directly mapped to wsdl:service element which exposes each contract as separate wsdl:port (in WCF known as endpoint). This is the main point in answering your question. If you don't want your second contract in that wsdl:service you can't implement it in the same class.
You have mentioned that your service contracts share resources. In that case your WCF service probably also contains business logic. That is a reason for your problems. The good design for implementing WCF services is to create them only as wrappers around separate business logic classes.

Related

Multiple WCF service implementations at one address?

I currently have several C# service implementation classes, each of which implements several service contract interfaces. Each service implementation class is at at a separate address, but all of its service contract interfaces are at the same address.
A client that wants to use interfaces from several services currently needs to know about several addresses.
I am wondering if it is possible to have several implementation classes share an address. For instance, currently, a client might connect to Browse.svc, Data.svc, Report.svc etc. Could I reconfigure so that the client only needs to go to Service.svc?
It seems to me that the SOAP Action provides a means for WCF to tell to which service implementation class it should direct the request, so this might be possible.
I really don't want to slam all my implementation into one big service class.
The following Microsoft article talks about this sort of thing, but doesn't seem to address the issue of multiple service implementation classes.
http://msdn.microsoft.com/en-us/library/aa395210.aspx
If you want one service, that can respond to multiple service requests. have a look at http://davybrion.github.com/Agatha/
It's an implementation of the request/response pattern for WCF.

WCF: Why is Contract on Endpoint and not on Service?

Trying to really 'get' endpoint contracts:
I understand offering different endpoints to support different bindings, but when would one define n endpoints for a service, and use different contracts? Seems that in most cases (bar IMetadataExchange) the endpoint contract would be the same no matter the protocol, no?
If most of the time the contract would be the same across all endpoints, would it have been too simplistic (and why?) to define the service contract on the parent service instead of on each endpoint (seems cumbersome/repetitive), while alllowing an override on the endpoint for when needed (eg: IMetadataExchange).
Thanks for help with the small questions that keep me up at night ;-)
OK, well - the service that you define in the <service> tag is the actual implementation code - the actual C# or VB.NET lines that make up the service. Therefore, it's a concrete class (which might even implement multiple service contracts). This is server-side only.
The endpoint however is the communications channel between the server and the client, and between those two, you want to share only the contract - never any concrete implementation of that contract. The endpoint will only ever be used for a single service contract - if your concrete service implements multiple contracts, you need to expose multiple endpoints to the clients to provide all that functionality.
Does that make things a bit clearer?

WCF Multiple Endpoints and IServices

I am just trying to get to grips with using WCF, and I am wandering if someone could tell me if I have the right idea with endpoints.
I have been working through the videos on msdn, and now I am wandering about the way to configure WCF Service. The scenario is if I have multiple IServices, e.g. such that I have an IThis and IThat, and the client needs the access both (note: they will be using net.tcp),
IThis handles database querying and,
IThat handles calculations independent of the database,
I assume that I have to define separate Endpoints for IThis and IThat, that are referenced in the client separately. Or would I create an overall IThisAndThat Service that gets referenced in the client and contains the functionality for both??
Or is are the other ways for developing and handling WCF Services with multiple IServices? While I'm asking can you define base address for tcp or only http?
~Thanks all, any help or pointers would be great.
I assume that I have to define
separate Endpoints for IThis and
IThat, that are referenced in the
client separately. Or would I create
an overall IThisAndThat Service that
gets referenced in the client and
contains the functionality for both??
You can do both:
you can create a separate service implementation class - one for IThis, another one for IThat
or you can create a single service implememtation class that implements both IThis and IThat
That choice is entirely up to you.
For every service implementation class that you have, you can define any number of endpoints you wish to have. So if you have an ThisService implementing IThis, you can define a HTTP and a TCP endpoint for that, and you also have a ThatService that implements IThat for which you define a TCP endpoint. That's totally up to you.
BUT: you can only define your endpoints for each service implementation class - if you have a ThisAndThatService implementing both service contracts, you cannot define 3 endpoints for IThis and two different ones for IThat - the endpoints you define are per service implementation class.
While I'm asking can you define base
address for tcp or only http?
Yes, absolutely - you can define a base address for each of the various addressing schemes (http, net.tcp, net.msmq, net.pipe and so forth).
Some basics:
Each service has one or more endpoints. The endpoints are specific to their relevant service, i.e. each endpoint can only belong to one service and cannot be shared between services.
An endpoint defines an entrypoint to the service - it includes an address, binding and contract that can be utilized by a client.
Different endpoints must have different addresses, and can have different bindings and contracts (i.e. they do not have to). Typically, different endpoints have different bindings - that is, transport protocol. They can have different contracts if particular clients are only supposed to have access to certain operations.
Finally, your service must implement all of the contracts that its various endpoints expose.
Here's a very concise and straightforward MSDN page which describes these concepts. http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/9f4391e9-8b9f-4181-a081-860d42b992a9/
There's a lot of information on WCF on the web, and there's a lot to learn. Best to look at some tutorials or guides which focus on what you are trying to do.

WCF - how to separate different functionality at an endpoint

I have Modification, Retrieval and Administration operations that are implemented by WCF services. I would like to separate them. The first thing that came to mind was to have three interfaces IRetrieval, IAdministration and IModification and create endpoints based on these interfaces. However, another developer said something about using different bindings or ports. I don't think that's possible - my understanding that WCF binding only defines how the data is treated over the wire and is not fit for logical separation. Am I in the ball park? Are there any other ways to separate the functionality besides the interfaces?
There are only two ways to separate functionalities: separate contracts implemented on the same service or separate contracts implemented on separate services. The difference between these two are more like logical and physical separation. For example default WSDL generation exposes metadata from all implemented contracts in a service. So if you implement all contracts in the single service and expose a metadata endpoint, each client will know an exact description of your administration methods and what security is used.

WCF ChannelFactory against SOA principles?

Is sharing a project containing the wcf interface and datacontracts and using these via ChannelFactory to consume the service against SOA principles?
My architect is advising that generating a proxy using Add Service Reference is preferable.
I guess that depends on a some things: your infrastructure, security policies, governance, etc.
We design our WSDLs (service and message contracts) and XML Schemas (data contracts) and then use svcutil.exe* to generate a proxy. At that point, we have code we can either use to consume or stand up a service. Of course, I am just talking about the code, the output.config will be modified with proper behaviors, bindings and endpoints as those are decided.
Once the service is stood up, it's fronted by an XML gateway. At which point we can begin testing the services using the 'Add Service Reference...'. If you're just looking to save some time and hand someone else your pre-generated proxy or your WSDLs aren't exposed (as they're behind an XML gateway that does not echo them), then what you're doing seems fine.
Otherwise, I'd expect consumers to be able to 'Add Service Reference...' and generate their own clients.
*Java-based applications use something else (WSDL2Java/ClientGen/built-in IDE tool).
Sharing pre-packaged service interfaces along with datacontracts isn't against SOA principles as long as consuming services are not expected to use it. This is exactly what enables potential clients to speed-up development against an existing 3rd-party service, or begin development against one which is yet to be built. Providing interfaces/datacontracts in code format will be less ambiguous than describing these things via documentation only (of course they may not be useful if the client is using a different programming language).
However, if some sort of pre-packaged implementation of the service interface is provided in the shared package, and this implementation is required to be used to successfully use the service, then this would be against SOA principles unless an implementation was written for all types of clients. Being pragmatic though, this can be a good idea so the clients can be more loosely coupled against things such as transport choice, service contract changes and service versioning.
I would recommend using the ChannelFactory (from a dotnet client of course) whether consuming the services via a shared pre-packaged interfaces/datacontracts project or dll, or generating your own proxy (via 'Add Service Reference' or 'svcutil.exe'). This will allow you to code against the service interface and therefore your client will be much more friendly to using concepts such as dependency injection for stubbing, testing, etc.
Both methods of generating a proxy are valid, it depends on how much control you wish to have over the proxy, and if you own both sides of the code. A third option also exists, you can hand craft your own proxy. Let me explain further:
In SOA we pass messages, this is a different paradigm to passing pointers to objects on a heap/stack which is the norm in OO world.
Thus in SOA, the contract (what you can do) and the message (the state to act upon) are important and need to be shared with the consumers of the service so they can all agree on the contract or "rules of engagement" here we have the most basic form of SOA.
Enter WS-* a set of specifications for adding more functionality to our service call (distributed transactions, security etc...) but if we do this we all need to agree on the rules and the flavor of the type of interaction we intend to use, so the service and its clients need to agree exactly on how this is to occur so it to needs to be shared.
The combination of the contract definitions and WS-* specifications is called a WSDL and this typically is what get shared between clients and services, this is in line with the SOA tenants that we share schema and contract, not class, and that Compatibility is based on policy (WS-*).
So if you use channel factory you generate the proxy based on the interface definition you have and the config you have set up on the fly, if you use add service reference you let the IDE generate a proxy class based on the WSDL of the service as it exists then.
If you hand craft the proxy, you have full control over how this happens and you can jump into the interception chain and do things on the client side to manipulate the call.
Depends on what you want to do.
The standards we have carefully considered and adopted at my company, are that we distribute service contracts is two ways. As a shared assembly when delivered to teams within the company, and as a WSDL when providing to clients and other third parties. It is a standard we discussed with Microsoft during a design / process review and they agreed was the correct approach.