In the wcf duplex project I am working on, proxy is created and opened using the following 3 lines:
InstanceContext context = new InstanceContext(new MyCallbackObjectImplementingCallbackContract());
_proxy = new ServiceClient(context);
_proxy.Open();
I have a couple of questions here:
Lets say my callback contract has just 3 methods(operation contract) and on my callback class, on top of just implementing those 3 I have like 10 more methods.
I found by debugging on server side when
OperationContext.Current.GetCallbackChannel<IMyCallbackContract>() is called
the object returned has only the methods with attribute 'OperationContract', and not the whole object. What is the magic behind the scenes. Also, is it not a bad design to have bunch of extra(not contract implementations) methods on call back class, if so what impact could it possibly have?
_proxy.open() metadata says object to transition from the created state into the opened state. I don't quite get what that means?
Question #1: Yes, WCF only looks for methods marked with OperationContract attribute. It creates proxies using the old Remoting RealProxy/TransparentProxy mechanism. Basically, WCF looks for operations in the contract interface, not in a class that implements the interface. It also proxies the contract interface, and not an implementation class.
As for the design question, it depends. As long as the other methods help the operation methods fulfill their contract, there is no problem. But if the other methods implement a different responsibility, then as it sounds, such design violates the single responsibility principle.
Question #2: in WCF, channel proxies inherit CommunicationObject. This object is not stateless, it tracks state of communication over the channel. Moreover, it can hold a session on the remote side, which is an expensive and limited resource. For these reasons, communication object should be treated much like database connection: open it, execute the operation, then Close() or Abort(). You can find more details in this MSDN topic.
Related
I have changed a former WCF one-way service to a duplex service so I can implement callbacks.
My actual problem is since that change, every piece of code that instanciates the service proxy needs to be modified to pass an instance context as parameter into the constructor.
There are many, many places in a few different projects that make use of that service. Everyone of them is now broken.
Will I be forced to go back in every proxy instanciation and pass an instance context into the constructor ? Can I avoid this ?
Simply speaking - no you cannot avoid this.. Presumably you need the duplex service for one WCF call to be able to callback... I would probably just create a separate method on the interface rather than changing the existing one so that you don't break the contract between service and client.
I've just begun learning WCF, and I'm coming from a total non-web background.
I have built a 3-tier desktop application, which compiles into one exe, which runs locally.
Now I want to move the whole business logics layer to a centric server, and make the GUI a client application.
As far as I understand, WCF should be my solution, as indeed, it helped me achieved what I wanted.
I mange to run remote functions, which is the basic of what I need.
My problem now, is that I don't quite understand the architecture.
For example, one of my services, returns a data type (class), from my Business Logics layer.
This class automatically becomes available to the client through the WCF mechanism.
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
For example a Save method (saves to the db).
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
What should I do? Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I know this is a basic question, but honestly i've searched a lot before asking here. My problem is I don't quite know what to search.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
Typically, if you want to encapsulate your business layer, you would not want to expose the business objects directly. This is because you now have a de-coupled client and you don't necessarily want to have to update the client every time the business logic/properties change.
This is where Data Transfer Objects (DTO) come into play nicely. Usually, you want to have control over your contract (data and methods) that you expose. Therefore, you would explicitly make other objects (DTOs) that make up the transfer layer. Then, you can safely change your client and server code independently (as long as both still fulfill the contract objects).
This usually requires a little more mapping (before you send or receive on each side) but it is often worth it.
For WCF, your interfaces and classes marked with [ServiceContract] and your classes marked with [DataContract] usually make up this transfer layer.
In WCF to expose method to client you have to mark it with OperationContractAttribute. So if you don't want clients to use your Save method, just don't mark them with with this attribute.
More info here: http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx
Pretty much same thing with properties, but different attribute: DataMemberAttribute. If you don't wont client to see it, just don't mark them with it (DataMember attribute)
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
Are you able to provide an example of your class and interface code? If so I'm sure you might be able to get more specific answers.
For example a Save method (saves to the db).
One possible approach would be to separate your class into 2 classes. Define the properties in the first class and then use that class as the base class of your second class. Then use the second class to define the methods. This would allow you to return only the properties while allowing you to keep your code DRY.
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
While you are able to define logic in the get and set methods for each property I would highly recommend revalidating any input received between services simply because any future changes or errors in one service could potentially lead to larger problems across your application. In addition this also helps to ensure your application is more secure against any potential attacks.
Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I agree with the above answers that you should be able to limit access to the different properties and methods using the data and method attributes within your interfaces.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
If you are looking for inexpensive but highly valuable video based training I've found the courses that Pluralsight offers to be quite good for both architecture as well as WFC services (btw, I am not associated with them, just enjoyed their training).
In IDesign WCF coding standard it says :
"Do not duplicate proxy code. If two or more clients use the same contract, factor the proxy to a separate class library."
I would like to know what is the advantage of the above state ?
Apart from the general principle of DRY (don't repeat yourself), it avoids the potential confusion of having multiple types with the same names and members.
Of course if your two or more clients are totally independent (separate Visual Studio solutions), it's OK for each to have its own proxy.
To me it means that if you use a proxy method in more than one place, don't duplicate that code, instead move it to a separate class. For example, if you regenerate the proxy because an operation has been changed, you have to change your code everywhere you've used that operation. If that operation is only used in one spot, your code is much more maintainable.
This is also a good approach to encapsulate proxy usage and ensure the proxy is being used properly (channel is closed when finished, exceptions handled properly, channel aborted if exception caught, etc).
I recommend that if you are going to use the proxy approach that you do not use Visual Studio Add Service Reference to generate that proxy. If possible, consider using a ChannelFactory implementation.
What's the purpose for MarshalByRefObject?
Remoting; it means that between AppDomains or machines, rather than serialize and transfer the object, the object stays at one end and a proxy is created at the other. All method calls to the proxy are intercepted and the call is transmitted as RPC wiki, msdn, causing the method to execute on the other machine (typically serialising the arguments and return value).
Note: this can lead to unexpectedly "chatty" interfaces. The object/proxy/RPC approach is now less preferable to approaches with an explicit service boundary; Microsoft now recommends WCF wiki, msdn instead of remoting.
Another important use of MarshalByRefObject is for implementing AOP via remoting sink-chains.
If you have an object that derives from ContextBoundObject (which itself derives from MarshalByRefObject) you can instantiate it in a separate Context within the same AppDomain and have communications between objects automatically go through the Remoting proxy system - allowing you to plug custom sinks into the Remoting sink-chain.
This ultimately allows you to 'decorate' method calls to your objects and implement cross-cutting services, such as logging and security etc.
it basic use is for support access of objects between two appdomains and these appdomains can be on the same computer or in the different computers via remoting.
See Here
Any object outside the application domain of the caller application should be considered as Remote Object. A Remote Object that should be derived from MarshalByRefObject Class. Any object can be changed into a Remote Object by deriving it from MarshalByRefObject. Objects without inheriting from MarshalByRefObject are called Non-remotable Objects.
I just wanna learn why I can't static web methods in web services ? Why is it restricted ?
Can some body give me concise explanation of this.
The answer is: because you can't.
It's not designed that way. The design is that an instance of the web service class will be created, and then an instance method will be called.
I can only guess why Microsoft designed it that way. To know for sure, you'd have to ask them. Consider:
There's no particular benefit to permitting static methods. Anything you can do with a static method, you can also do with an instance method.
A [WebService] class is not meant to be some arbitrary class that happens to be used as a web service. It's meant to be a class that you created for the purpose of exposing web service operations. As such, there is no need to support classes that already exist and already have static methods.
The SOAP Header implementation permits your class to contain an instance field of a type deriving from the SoapHeader class. This field will be filled with an incoming SOAP header and/or will contain the SOAP Header to be returned. You could not do this with a static field, as it would be overwritten with each request.
As I said, these are all guesses. The correct answer to the question is, "you can't because that's how Microsoft designed it. If you want to know why they designed it that way, you need to ask them".
FWIW, I just checked, and it does not appear that WCF permits static methods to be operations either.
When a client creates an object for your web service, what they are really creating is a proxy object to that web service. This proxy object handles things like opening and closing your connections for you as well as all the overhead of actually working with the web service. A static method call would be difficult to manage. The "static proxy" for lack of a better word would have to do all of things that the instance of the proxy object is doing each and every time a client called one of the static methods, thus adding massive overhead.