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.
Related
Lets say I need to call multiple services that insert some records with EF in the same transaction which are for inserting Person and Unit.
I'm uncertain for whether I should create a new operation contract named AddPersonAndUnit and use TransactionScope in that method and calling it from the client OR don't create any additional method and just use TransactionScope in the client (ASP.NET MVC client) and call AddPerson and AddUnit which are already existing.
For single responsibility and moving all business logic into service layer, I think defining an extra method in service layer and calling it from the client seems a better choice but on the other hand just calling these multiple methods from the client requires less effort.
What do you think with the respect of a good design choice? Do you think dealing with the transactions in client is "bad"? Is it worth it to create a new method for this?
Based on your question, you're having two projects (ASP.NET MVC & WCF) and you want to make sure Person and Unit are being inserted/updated transactionally
Taking those two as inputs
Let's do quick analysis about option 1 (Use TransactionScope in client code (proxy class))
Efforts needed
Modify Service Contract classes (OperationContract and ServiceBehavior) to support transaction
Decorating existing methods (OperationBehavior) to suppor transaction
Modify binding config
Re-config client binding configuration
PROS (CLAIM TO BE):
Requires less efforts => As described in point 1., in my opinion, it's difficult to say this method requires less efforts to implement unless everything was is in place
CONS:
Since both application code (MVC) and service code (WCF) are being controlled fully by you, you can make sure that you ALWAYS use the transaction when insert/update Person and Unit. However, I would prefer to make it as black-box service, so that I could expose it to other 3rd client or give the service to another developer to use without worrying about data inconsistency (what if they forgot/intentionally skip the transaction?). Even though you can force the client to ALWAYS use transaction when calling the web services (by using TransactionFlowOption.Mandatory option), I think the good practice is only expose minimal service for client to use
Single Responsibility is also another concern
Duplicate codes (you will need to copy the code over and over every time you want to insert Person & Unit)
Hope it helps,
Sorry for bad English
I'd like to be able to add a couple of behaviors without having to call a method forcing them to be to used. A typical example is via an [InvokeErrorSupport] attribute whose purpose would be to fire off a test e-mail when deploying a service to ensure the error e-mails are coming through okay. Thus saving magic strings in a request Parameter Object, one or more non-business logic related [OperationContract] methods etc dirtying up the contract (with single responsibility in mind). We are more than happy to potentially invoke a method in other case such as our [Heartbeat] behavior and similar.
I have no problem writing the behaviors. It's a great feature of WCF but right now its looking like I'm going to have to add some method to the contract which I call such as Initialize which I'd lock down after start-up. Since, in this instance and more, the services are often external facing so we wish to avoid DoS attacks etc.
I've poked about client-side and can't see anyway and to be honest it kinda makes a degree of sense this functionality doesn't exist.
Can anybody offer any advice?
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.
I need to invoke WCF service 1 or WCF service 2, based on certain condition evaluated at runtime. Both the services are similar but hosted on different servers.
I have added two service references, NS1 and NS2 pointing to different urls. Current code already uses NS1. Considering this NS1 implementation has already been done at many places. What would be best way to refactor the code, to select dynamically which service has to be invoked ?
In general, it is considered a bad practice to program directly against the proxy generated by the svcutil.exe.
The best way is to wrap it in a class of your own and reference this class each time you require the service. This will also allow you to implement more advanced business logic such as routing (in your case) and other cross cutting concerns.
For example: you can now abstract from the application the strategy you are using to connect to the service, i.e. Service reference or ChannelFactory. You can easily share the service between different assemblies without ambiguity.
You are saying that you have much code written directly against NS1. Grind your teeth and wrap it. It is a lot of dirty work but the risk is very low.
Having said the above, I wonder about the requirement itself, where a service calls another instance of itself on another server (if I got you right). This smells funny, what is the problem you are trying to solve?
I'm working on a project that relies extensively on Exchange Web Services. As of now I'm wrapping all of my service calls on try/catch. While this isn't a problem per say it does clutter code quite a bit by having one line turn into 10~.
Here are the options I see:
Create a function such as bool TryExecute(Action action, Action failCallback)
Interface all of my service calls and use an interceptor to wrap my calls
Are these any alternatives that I'm missing?
that depends on your implementation. I would place the try/catch as near to the point where failure is expected (and can be gracefully handeled) as possible.
For example wrapping those calls into a interface (for testing) and using only a common exception-type otherwise (for example handle EndpointNotFound and wrap any unexpected failure into a ExchangeCommunication-Exception you created yourself).
Both of your options seems to handle every kind of error, and I would not advise this but aside from that it's surely better than going against DRY