At first I treated them as any dependency passing them in the ctor to the class consuming the service:
var serviceConsumer = new ServiceConsumer(new MailingServiceClient())
The problem was that once an exception was thrown from the service it entered a faulted state and would not reply to any requests, so re-initialization was due.
Further more, I became familiar with the fact that wcf services may not be disposed properly on several occasions, because the dispose method of the generated proxy is broken (calls close without checking the fault state) and encountered a couple of ways to overcome that:
wrapping every call to every service.
override the default IDisposable behavior of the scvutil.exe-generated class
Since I wouldn't like the consumer code to create the service client himself for testing reasons, my questions are:
how can I maintain a working un-faulted service?
how can I still use dependency injection for testability?
Found a nice solution.
a proxy generator that replaces the VS one, and generates a wrapper around the default proxy that deals with proxy faults, timeouts, and correct disposal.
http://wcfproxygenerator.codeplex.com/
seems to be working fine for me.
Related
I'm hosting some SOAP services with WCF. How can I turn off these services via config for the purposes of maintenance, etc., and provide a friendly message to the service consumer with something like "The service you've requested is down for maintenance."?
You would have to have a second service, that offered the same interface, same methods etc., that would all return that friendly message instead of a real result.
That might get a bit trickier when those service methods don't just return a string but a complex data object - where do you put that "friendly" message??
In reality I think this cannot really be done - since your services typically aren't "seen" by actual people, you cannot just put up an app_offline.htm file or anything like that.
Try to have as little downtime as possible, by e.g. setting up your new version of the service on a new port and testing it there, until you're confident enough to switch over.
With WCF, it's mostly an exercise of updating / copying around the appropriate config, so your service should never really be unavailable for any extended period of time (hopefully!).
If you really must, what you could do, is just have a replacement service that will always throw a FaultContract<ServiceDownForMaintenance> - but then all the clients calling your service would have to know about this and they would have to handle this case and present an error or information message. Your service can't really provide that...
How about this: create a custom ServiceBehavior to intercept my incoming requests to the service. Then, have the custom behavior check a user-defined flag in my config file, something like <add key="IsMyServiceUp" value="true" /> and if that value returns as false then throw a ServiceException with my friendly message and HTTP code of 503 - Service Unavailable.
Does that sound reasonable? Then all I have to do is change the flag in my config file to specify where the service is up or down.
Okay, so I've created a new Custom Behavior that implements IOperationBehavior. In the Validate method, I've got
public void Validate(OperationDescription operationDescription)
{
bool isServiceUp = Boolean.Parse(ConfigurationManager.AppSettings["IsOrderServiceUp"].ToString());
if (!isServiceUp)
{
throw new ServiceException(ServiceErrorCode.Generic_Server_Exception,
ServiceErrors.Generic_Server_Exception,
SoapFaultCode.Server);
}
}
The other implemented methods ApplyClientBehavior, ApplyDispatchBehavior and AddBindingParameters are all empty.
I have decorated one of my service operations with [ServiceStatusValidation] which is the class name of my custom behavior.
When I start the service and navigate to the operation with this decoration, I do NOT get the exception I've thrown. SOAP UI shows nothing as returned in the response pane, and my consuming REST facade gives a generic 400 error with The exception message is 'The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.'.
Any ideas? Should I be doing this logic in one of the other methods that I didn't implement instead of the Validate method?
I have been trying to get up to speed on Named Pipes this week. The task I am trying to solve with them is that I have an existing windows service that is acting as a device driver that funnels data from an external device into a database. Now I have to modify this service and add an optional user front end (on the same machine, using a form of IPC) that can monitor the data as it passes between the device and the DB as well as send some commands back to the service.
My initial ideas for the IPC were either named pipes or memory mapped files. So far I have been working through the named pipe idea using WCF Tutorial Basic Interprocess Communication . My idea is to set the Windows service up with an additional thread that implements the WCF NamedPipe Service and use that as a conduit to the internals of my driver.
I have the sample code working, however I can not get my head around 2 issues that I am hoping that someone here can help me with:
In the tutorial the ServiceHost is instantiated with a typeof(StringReverser) rather than by referencing a concrete class. Thus there seems to be no mechanism for the Server to interact with the service itself (between the host.Open() and host.Close() lines). Is it possible to create a link between and pass information between the server and the class that actually implements the service? If so, how?
If I run a single instance of the server and then run multiple instance of the clients, it seems that each client gets a separate instance of the service class. I tried adding some state information to the class implementing the service and it was only retained within the instance of the named pipe. This is possibly related to the first question, but is there anyway to force the named pipes to use the same instance of the class that is implementing the service?
Finally, any thoughts on MMF vs Named Pipes?
Edit - About the solution
As per Tomasr's answer the solution lies in using the correct constructor in order to supply a concrete singleton class that implements the service (ServiceHost Constructor (Object, Uri[])). What I did not appreciate at the time was his reference to ensuring the service class was thread safe. Naively just changing the constructor caused a crash in the server, and that ultimately lead me down the path of understanding InstanceContextMode from this blog entry Instancecontextmode And Concurrencymode. Setting the correct context nicely finished off the solution.
For (1) and (2) the answer is simple: You can ask WCF to use a singleton instance of your service to handle all requests. Mostly all you need to do is use the alternate ServiceHost constructor that takes an Object instance instead of a type.
Notice, however, that you'll be responsible for making your service class thread safe.
As for 3, it really depends a lot on what you need to do, your performance needs, how many clients you expect at the same time, the amount of data you'll be moving and for how long it needs to be available, etc.
I have a WCF service which is a singleton and which manages a collection of proxies to another WCF service which is session-based. The singleton creates a new proxy and passes it some work to do, and the session-based service makes calls back to the singleton service when certain activities complete (pretty much all of the OperationContract methods are one-way). The typical completion path is that the singleton receives an event from a hardware device when the process is complete, and it calls a method on the session-based service which returns the final status, and then disposes of its proxy. When an error situation is encountered and the session-based service can't continue with what it needs to do, I need to make a call back to the singleton to let it know to dispose of the proxy associated with that instance. However, to make the WCF method call back to the singleton, I need to create a proxy back to the singleton. What I'm seeing happen is that the singleton disposes of its proxy as expected, but every time the proxy to the singleton that the session-based service created times out when I try to dispose of it. Since the session ends with that method call and the instance will be disposed of, does it matter if the proxy it created doesn't get properly disposed?
Disposing of a WCF service is not the same as disposing of any other object that implements IDisposable. It is ok to dispose of the service when it is in a good state but when a fault occurs the dispose method will throw another exception.
Some insight is here and perhaps use the WCFProxyGenerator but I have not tried it
Not sure exactly the problem with the session based service and whether it is different from the WCF service.
My recommendation is not to use a singleton but use Dependency Injection to give the class that uses the WCF service a factory so when it wants the service it can create it. And when a fault occurs it can throw away the old and create a new one. Without seeing some code it is hard to see if this is possible.
As the title implies I am trying to get an understanding of why in WCF sometimes people choose to "generate proxies" vs using a ChannelFactory to manually create new channel instances. I have seen examples of each, but haven't really found any explanations of WHY you would go for one vs the other.
To be honest I have only ever worked with channels and the ChannelFactory<T> from code I have inherited, ie:
IChannelFactory<IDuplexSessionChannel> channelFactory =
binding.BuildChannelFactory<IDuplexSessionChannel>();
_duplexSessionChannel = channelFactory.CreateChannel(endpointAddress);
So why would I "generate a proxy"? What are the benefits and drawbacks?
The main difference is this:
generating a proxy only requires you to know the URL where the service resides. By generating the proxy, everything else (the service contract and the data contracts involved) will be determined by inspecting the metadata of the service
in order to directly create a ChannelFactory<T>, you must have direct access to the assembly that contains that service contract T for which you're generating a channel factory. This only ever works if you basically control both ends of the channel and you can share the assembly that contains those service contracts. Typically, with a third-party service, this won't be the case - with your own services, yes.
The second important point is this:
creating a generated proxy basically does the two steps that you would do - create a ChannelFactory<T>, and from that, create the actual channel - in a single constructor. You have no control over these two steps.
doing your own Channel creation is beneficial, since the creation of the ChannelFactory<T> is the expensive step - so yo could cache your channel factory instance somewhere. Creating and re-creating the actual channel from the factory is much less involved step which you can do more frequently
So if you do control both ends of the communication, service and client, you do have the option to share the service contracts in a separate assembly, and thus you have more options.
With most third-party services, you just simply don't have that option.
Using a proxy is simpler and easier to understand. You get to deal in terms of simple things - classes and methods on those classes - instead of complex, network-related things like channels.
OTOH, this is not made easier by the design flaw in WCF that prevents the same simple use of a WCF proxy that we could do with ASMX proxies:
using (var client = new MyServiceClient())
{
}
If you use this pattern with WCF, you can lose the original exception when the block is exited due to an exception. client.Dispose() can throw an exception, which will overwrite the exception originally being thrown. A more complex pattern is required.
This may help you:
When to use a proxy?
If you have a service that you know is going to be used by several applications or is generic enough to be used in several places, you’ll want to use the proxy classes.
When to use ChannelFactory?
ChannelFactory class is used to construct a channel between the client and the service without the need of a proxy. In some cases, you may have a service that is tightly bound to the client application. In such a case, you can reference the Interface DLL directly and use ChannelFactory to call your methods using that.
You could also refer following link to understand the difference between Channel Factory and Proxy class
http://ashishkhandelwal.arkutil.com/wcf/channelfactory-over-proxy-class-in-wcf/
The main advantage of the channelFactory is you can create the proxy at runtime dynamically on the fly. With SvcUtil (Add web reference in VS) you create the proxy at design time, so it's implementation is more static.
I am using wcf 4 and trying to transparently transfer context information between client and server.
I was looking at behaviors and was able to pass things around. My problem is how to flow the context received in the incoming headers to the other services that might be called by a service.
In the service behavior I intercept the the message and read the headers but don't know where to put that data to be accessible to the next service call that the current service might make.
What I am looking for is something like:
public void DoWork()
{
var someId = MyContext.SomeId;
//do something with it here and call another service
using(var proxy = GetProxy<IAnotherService>())
proxy.CallSomeOtherMethodThatShouldGetAccessTo_ MyContextualObject();
}
If I store the headers in thread local storage I might have problems due to thread agility(not sure this happens outside ASP.NET, aka custom service hosts). How would you implement the MyContext in the code above.
I chose the MyContext instead of accessing the headers directly because the initiator of the service call might not be a service in which case the MyContext is backed by HttpContext for example for storage.
In the service behavior I intercept
the the message and read the headers
but don't know where to put that data
to be accessible to the next service
call.
Typically, you don't have any state between calls. Each call is totally autonomous, each call gets a brand new instance of your service class created from scratch. That's the recommended best practice.
If you need to pass that piece of information (language, settings, whatever) to a second, third, fourth call, do so by passing it in their headers, too. Do not start to put state into the WCF server side! WCF services should always be totally autonomous and not retain any state, if at ever possible.
UPDATE: ok, after your comments: what might be of interest to you is the new RoutingService base class that will be shipped with WCF 4. It allows scenarios like you describe - getting a message from the outside and forwarding it to another service somewhere in the background. Google for "WCF4 RoutingService" - you should find a number of articles. I couldn't find antyhing in specific about headers, but I guess those would be transparently transported along.
There's also a two-part article series Building a WCF Router Part 1 (and part 2 here) in MSDN Magazine that accomplishes more or less the same in WCF 3.5 - again, not sure about headers, but maybe that could give you an idea.