I know, I know, but before you vote to close because this 3-year-old question is the same: neither its answers, nor any of the dozens of other answers I've read and reread across the wide wide web, really define the term, at least not in a way that would earn a respectable grade on a language exam administered in a human-language class. (Technical writers appear to have a whole different idea of what "is" is.)
All due respect, consider the most-upvoted answer in that thread, which begins
An endpoint is what a service exposes, and in WCF terms, is made up of
three things...
Okay, that's how it's utilized and what its attributes are. What is it? It's an address, a binding, and a contract, easy as A-B-C! Any good student knows a "Binding" is just an(other) abstruse term for a communication mechanism, and a "Contract" is actually part of the service itself. So an endpoint must be defined by the "Address"!
The URL by which the endpoint can be reached.
Um... then how about the canonical Lowy answer, also cited in that thread. An excerpt of the part that doesn't repeat the above:
The endpoint is the fusion of the address, contract, and binding.
Every endpoint must have all three elements, and the host exposes the
endpoint.
That's like saying a duck is the fusion of walking like a duck, quacking like a duck, and looking like a duck, and the animal kingdom exposes the duck.
All snark aside, this is not idle gadfly curiosity: it is very hard to master a concept whose explanations fail to explain it. So, what is an endpoint in WCF?
An endpoint is really is an aggregation of these things, it's not an entity or concept that exists in its own right as such.
To extend your duck analogy, it's more like trying to define the quack itself - a quack is the aggregation of air moving over the duck's vocal cords, travelling through space and being interpretted by your brain. There is no "quack" you can point at and define separately outside of those terms.
An endpoint represents something that an external client call to ask your service to do something and (optionally) get some answer or data returned. As Ladislav says it's an "entry point to service functionality".
In order to define what a client can call upon you to do you need a contract (interface definition). To define how the client should send the data and receive the answer you need a binding. To define where the request must be sent you define the address.
If you don't define one of those you don't have an endpoint.
We simply say an "endpoint is exposed" as shorthand for "the service defines contract "C", with binding "B" at address "A" (the ABC's) ", that's all there is to it.
Endpoint is physical interface (boundary) for your service which has three main properties
Address which you must use to reach the service
Binding = set of configurations you must follow to be able to communicate with the service
Contract = set of operations which you can call on the service
Service can have multiple endpoints with different ABC.
Btw. it is not WCF term. WCF brought this term from WSDL.
Endpoint usually is the contract the service are using - the interface it are using.
Related
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?
Is it possible to create a "generic" as in "adaptable" routing service, which will NOT have any public methods to call. Instead, you'd be able to call any command, which would then be mapped in the service and will pass it to appropriate end point with simple message transformation where required.
It may be hard to understand and idea might seem a bit crazy (it came from a colleague of mine), but it's clearer if you look at the example:
similar to what's described in this article, only difference is that our service should not have a "SubmitTimeSheet" public method, in fact it should have no public methods to call. We'd have to "intercept" an incoming call on a much lower level before it returns "Method Not Found" error.
Is this at all possible? The reason for this is obvious: possibility of adding new clients without having to change the code. All we'd have to do is to add a new mapping entry in some sort of config file or even database, e.g.
<Client address="newClientAddress" method="DoAnything" transformation="NewClientDoAnything.xslt" endPoint="endPointClientAddress" endPointMethod="endPointClientDoAnything" />
Check out WCF 4 routing - supports content based routing, xpath transforms and much more.
http://blogs.msdn.com/b/routingrules/
They have already done it in Nirvana. But it is very expensive.
This is not possible in WCF unless you define your contract as a very loose, fit-for-all contract which takes a message and returns a message. By doing this, you will los all the goodness (although not huge goodness in WCF) of 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.
I have a data contract say User. It is serializable and goes across the wire. I want an Operation Contract SaveUser(). I can keep SaveUser(User user) in my service contract as an operation contract. But can I keep it inside my data contract itself as its own behavior?
Save() should ideally save itself. So as per OO principles, every data contract should know how to save itself and the details should be abstracted from the outer world.
Is this possible in WCF?
I would say no, and rightly so.
Though I agree with you on the OO principles and encapsulation, WCF deals with SO (Service Oriented) principles.
Think of this in terms of a CD Player and CD's. The CD Player is the Service. The CD is the Data Contract. OO principles would call for the CD to have a Play method in order to be able to play itself. But, there is a lot more to playing a CD than knowing it's data. There is the electronics, the interface to the output jacks, etc. These are all provided by the CD Player...the Service.
So that is why your Service Contract has the Play method, and accepts the CD as a Data Contract telling it WHAT to play (and not HOW to play it).
EDIT after the question in your comment:
No certainly (hopefully) not. The worst case is that you will have 34 Service Contracts, each with on average 6 methods. And this is only the case if you are sure that every one of the methods on each class MUST happen as a service operation. There are 2 aspects you need to consider. Aspect 1: The design of your services. Instead of 34 Service Contracts, you should group the 34 classes into a grouping that makes sense, and create 1 Service Contract per group. Eg, you may end up with an InventoryManagement Service, and a SalesOrderProcessing service and a BackOfficeOperations Service. Each of these services contain the service operations (and Data Contracts) relevant to the range of classes grouped into their domain.
Aspect 2: What is happening on the client. I mentioned that you must consider whether each class's methods MUST be WCF Service Operations. There certainly is a case for having rich fully encapsulated business classes on the client. And where their operations don't need to execute as service operations, these operations execute their logic in the client domain. The question becomes how to get them to the client via a service, and here you have two alternatives: a) instantiate an instance on the client, and populate it's properties from the DataContract returned by a service operation. b) return the object directly from a service operation, as is done in a framework like CSLA (and I think DevForce follows a similar approach for returning business classes via a WCF Service).
HTH
I have a WCF service that supports about 10 contracts, we have been supporting a client with all the business rules specific to this client now we have another client who will be using the exact same contracts (so we cannot change that) they will be calling the service exactly the same way the previous client called now the only way we can differentiate between the two clients is by one of the input parameters. Based on this input parameter we have to use a slightly different business logic – the logic for both the Client will be same 50% of the time the remainder will have different logic (across Business / DAL layers) . I don’t want to use if else statement in each of contract implementation to differentiate and reroute the logic also what if another client comes in. Is there a clean way of handling a situation like this. I am using framework 3.5. Like I said I cannot change any of the contracts (service / data contract ) or the current service calling infrastructure for the new client. Thanks
Can you possibly host the services twice and have the clients connect to the right one? Apart from that, you have to use some kind of if-else, I guess.
I can't say whether this is applicable to you, but we have solved a similar problem along this path:
We add a Header information to the message that states in which context some logic is called.
This information ends up in a RequestContext class.
We delegate responsibility of instantiating the implementation of the contract to a DI Container (in our case StructureMap)
We have defined a strategy how certain components are to be provided by the container:
There is a default for a component of some kind.
Attributes can be placed on specializations that denote for which type of request context this specialization should be used.
This is registered into the container through available mechanisms
We make a call to the Container by stating ObjectFactory.With(requestcontext).getInstance<CONTRACT>()
Dependencies of the service implementations are now resolved in a way that the described process is applied. That is, specializations are provided based ultimately on a request information placed in the header.
This is an example how this may be solvable.