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

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?

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 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.

Shape a WCF service by endpoint

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.

WCF: Separate service per Business Entity

If for example, you have customers, orders and products. Do you create a separate service for each of these business entities?
It kinda feels logical that you should create a service contract for each of these. However, since you have to explicitly specify the contract that your service will implement… this sort of forces you to create a separate service for each service contract, does it not?
Could you please tell me how you would handle this? Somehow it feels ungainly to have a service for ever business entity… :-(
In advance, many thanks and regards.
Services act on business entities, but are not business entities.
So customers, orders and products would be data contracts, not service contracts.
It's the actions you perform on those data contracts that form your service contract, and the actions you expose on an entity may or not be all the things that entity can do.
If, as I think you might be asking, each entity has common functionality (CRUD operations for example) then yes, you should have a separate service contact for a CRUD service on each entity (CustomerCRUDService, OrderCRUDService etc.) because web services don't support overloads on method signatures.
(From the comments)
There are a couple of ways.
1) Composite service contracts: For example I have a service that implements WSTransfer - this actually is comprised of two service contracts, IWSTransferResource and IWSTransferFactory. In turn I have an IWSTransfer service contract that just implements those separate contracts - public interface IWSTransfer : IWSTransferResource, IWSTransferFactory
2) But you don't even have to get that complicated, an implementation in WCF can implement multiple service contracts - MyServiceImpl : IMyContract1, IMyContract2. However each contract needs a separate endpoint, because endpoints are for service contracts, not implementation classes.

wcf service to service communication & data contract

i have recently been involved in developing a WCF service which acts as a kind of multicast relay (i.e. accepts some incoming data, does some processing and then sends it off to multiple other external services). this service (which i will refer to as "my service") is fed data by a second internal service.
this data is going to be relayed from my service as XML held in a string. therefore my service could simply accept a string as an parameter to a method request - but this is not ideal as we lose type safety.
the second service has a class that encapsulates all of the information which my service requires to be processed, and eventually relayed to the external services.
the second service exposes this class in it's data contract. Ideally, in order to maintain type safety, and without requiring lots of changes to the second service's implementation, i should accept this type of class as an argument to my service operation.
what would be the best way for me to say in my datacontract that i require this type of class without duplicating code? could i add a service reference to this second class, and then use the proxy class which is created in my data contract?
i just can't get my head around this, even though it seems like a trivial problem!
cheers for any help!
If you are trying to avoid duplication of classes, put your class declaration in its own assembly and share that dll between all parties in the WCF Service. When you create your service reference you can choose which assemblies are shared (assuming you use the VS GUI service utility).
The use of a proxy class might be a good avenue as well. If you expose your main data class as a data contract, then create a proxy of that, the proxy will have a version of the exposed class that can be used by your other services.