My endpoints specify which interface is used to govern the WCF service. Because it's an interface, I can have multiple different concrete classes implement the interface's functionality. How do I specify which concrete class should be used for a given WCF service's endpoint?
How do you say for this endpoint, use this concrete class and for that endpoint, use that concrete class when both endpoints use the same interface?
The contract implementation type to use is defined when the ServiceHost instance is created. If you have multiple endpoints served by the same ServiceHost, it will create an instance of the same type to respond to requests to these endpoints.
If you want two endpoints for the same contract to use different implementations, you have two choices:
expose the two endpoints on two separate service hosts. (Either through creating two ServiceHost instances or specifying two <service> configuration elements);
have a composite implementation for the class that has two separate implementations of the same interface (through any OOP approach you can think of) and dispatches the calls to these based on the endpoint address.
I personally would stick with the first approach. If you go for the second approach, you would be essentially reimplementing ServiceHost yourself.
Related
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.
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?
I would like to declare an interface in my Web Service layer and then have the caller create objects of this interface type via proxy and use them to call the service methods.
However, when I decorate the interface with DataContract attribute, I get an error saying this attribute can only be applied to class, struct and enum. I don't think that ServiceContract attribute makes sense, as the interface I am trying to expose is used only for data transfer purposes. I also noticed that when the interface was decorated with ServiceContract, it wasn't displayed in the proxy class created.
What is the best practice to go about this?
You cannot do that. "DataContract" interface cannot be exposed as part of metadata. Also even if you share the interface (in assembly) your clients will not be able to send their implementation back to your service because receiving side needs real type for deserialized instance.
The service contract is used on the interface, that is the name of the services. The data contract is used on the class, the data that you are sending over.
ServiceContract on the interface
OperationContract on the methods
DataContract on Class
DataMember on properties
See: http://msdn.microsoft.com/en-us/magazine/cc163647.aspx
I wrote a couple of simple web methods (as a part of WCF service) that use a couple of (more complex) classes as input/returned parameters. Each web method attributed by [OperationContract], each data class attributed by [DataContract], each data field in the classes attributed by [DataMethod].
On the client side I can call these web methods by adding Service Reference.
All things are fine, but when I create an instance of some of the data classes above on client side, their constructors don't run.
Because it's a little complicate to initialize each instance, every time, I thought there is some way to initialize instances on client side by their own constructors.
Thanks in advance!
Ilan.
Methods exposed on data contracts (including constructors) in your service are only for service applications. Adding service reference will recreated only data structure of your data contract classes because service description is not able to describe logic and logic cannot be serialized.
All classes created with service reference are partial. You can create your own partial class and add your own custom constructors or you can share the assembly with data contracts between your service and client (but it will share all logic added to your data contract classes which is most often what you don't want). Sharing assembly will tightly couple your client and service.
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.