Why does .net WCF Service require the Interface
Unlike the asmx implementation the wcf requires for you to implement it's interface. I do not quite understand the reason behind that design. Interface is a contract between 2 classes...With that being said, how often do you have 2 wcf services that satisfry to the same interface but being implemented differently?
Another comment, the msdn strongly recommends to do this:
MyService service = new MyService();
try {
service.DoWork();
}
catch(Exception) {}
finally {
service.Close();
}
So let's say if I am to inject my serv开发者_如何学Goice with using it's interface like this:
public MyComponent : IDisposable
{
readonly IMyService service = null;
public MyComponent(IMyService service) {
this.service = service;
}
public DoWork()
{
//some additional code.
this.service.DoWork();
}
public void Dispose()
{
//The Interface does not have the Close method,
//So doing this defeats the whole purpose of polymorphysm
(this.service as MyService).Close(); //Silly.
}
}
How do you take the advantage of the interface with WCF?
No, WCF does NOT require you to have an interface and implement it.
It's just generally accepted best practice to do so - but you don't have to, if you don't want to.
If you want to, you can put your [ServiceContract]
on a concrete class that has a number of [OperationContract]
service methods - there's nothing stopping you from doing so.
But again: it's generally accepted and preached best practice to use an interface to separate out the actual contract as an interface (so you can e.g. mock it for testing etc.).
Actually, even MSDN concedes from time to time that the formality of interfaces may not always be "the right thing to do":
http://msdn.microsoft.com/en-us/library/ms733070.aspx
"The advantage of creating your services by applying ServiceContractAttribute and OperationContractAttribute directly to the class and the methods on the class, respectively, is speed and simplicity."
You can create a WCF service without using an interface:
[ServiceContract]
public class TheService
{
// more stuff here
}
That said, it is recommended to separate them. Separating the contract from the implementation can give you some different advantages:
- You can put the interfaces into a separate assembly. This assembly can be used by any piece of code that needs to know about the interface, but not necessarily about the implementation. I have used this sometimes to construct a sort of service gateway wrapping communication to the service.
- You can have one class implement more than one interface. This means that you can expose the same implemented class in different ways using different interfaces in the WCF endpoints.
There are other reasons, but these come to mind immediately.
in dotnet interfaces are used for describing behaviour. WCF, Web-services and remoting this all technology uses RPC (Remote Procedure Calling) behavior. in RPC there must be some common binding which shared by client and server.
if you use classes instead of interface, you've share your resultant dll file to client also. hence your logic goes to client side, which is not good practice. that's why we are using interfaces.
If you create a service without an interface then you lose the ability to create a channel on the fly in your code. Then the only way you can access the service is by adding a service reference.
Tried with default VS 2015 WCF service template; marked the service class with ServiceContract and the methods with OperationContract attribute. The IService1 interface implementation is removed (no interface implementation).
[ServiceContract]
public class Service1
{
[OperationContract]
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
[OperationContract]
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
With this change we cannot create proxy channel on the fly which I tried with below piece of code.
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost:59420/Service1.svc");
// InvalidOperationException is thrown as below line
// Error message "The type argument passed to the generic ChannelFactory class must be an interface type"
ChannelFactory<Service1> myChannelFactory = new ChannelFactory<Service1>(myBinding, myEndpoint);
// Create a channel.
Service1 wcfClient1 = myChannelFactory.CreateChannel();
Console.WriteLine(wcfClient1.GetData(1));
Console.ReadKey();
If we use and implement interface as below
public class Service1 : IService1
then code below runs without any issue. Please now Service1 is now replaced by IService1 interface while creating ChannelFactory object.
ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint);
This is the most important aspect if your client uses ChannelFactory instead of ServiceReference to access service.
精彩评论