As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
My application is currently made up of 2 different solutions.
1) The Shell which contains all the WPF and front end logic
2) The BackEnd which contains all the WCF service implementations and NHibernate related data access. At the moment, there are 6 different WCF service contracts defined.
I currently have this working quite well in Visual Studio but need to consider the deployment options for when the application is installed on to a users PC. As far as I am aware there are numerous different ways of hosting WCF services -- in-process, as a Windows Service, in IIS. I am intrigued to know how people go about configuring this type of setup in a Prism application.
The nearest info I have found so far is from http://wcfguidanceforwpf.codeplex.com/releases/view/27987 but I don't think it is quite what I am looking for.
I would like to know :-
a) How and if you can allow the users the choice of different hosting strategies for WCF services?
b) All the examples I have seen show the ServiceHost opening and starting one service. Is this the recommended practice and I would have to create 6 Service hosts or could I start six WCF services in one ServiceHost?
c) If the WCF services are run in process for testing locally for example - do you use the bootstrapper in the Shell and open all 6 WCF services or is there some other place that this happens?
d) What strategies you use for configuring the endpoints or is it simply a case of modifying the app.config files?
e) If there are any decent references online or book that I have not managed to find that cover Prism desktop / WCF configuration?
Apologies for the amount of questions but usually I can piece together an idea of what I need to do from extensive Googling but on this occasion I cannot find anything other than the link above that seems to match what I need to know.
Any help with this on any question would be most appreciated.
Alex
Let me begin by saying that Prism and WCF are mutually exclusive frameworks, and the use of one does not preclude the use of the other in any way.
a) Why would you let them decide how to host their WCF service? The easiest configuration is IIS hosting, which requires minimal setup. One IIS web could host all of your six services, unless you needed a memory barrier by putting each one in a separate application pool. Running the services in a Service Host is tantamount to writing an EXE (e.g. Windows Service) to serve the client. A lot more work and configuration (from the Windows Service side, WCF configuration is the same, unless it conflicts with IIS by running on HTTP:80). You have many options for the how, but you're using WCF, so I assume you have a client/server scenario. If you have a Windows server, use IIS, imho.
b) You can run as many WCF services inside the same Service Host as you want, but if one fails, the whole EXE crashes. That is why I suggest IIS application pools, which auto-restart on failure, and can be configured to run each service in a different application pool.
c) There are different strategies for where to put service integration code, depending on how your application is structured. I would suggest writing a "Service" class for each of your WCF services and register each with your container, so you can use an ImportingConstructor on your view models that need any particular one. You would initialize and register these classes in the bootloader. At this point you may be asking yourself if you really needed 6 and maybe should consider consolidating into 1 WCF service.
d) I disagree with Sebastian here. WCF configuration is simple if your service is simple. The more complicated you need it to be, the more complex the configuration. By default, you need very little configuration, and I would look at the WCF Service Configuration Editor tool included with Visual Studio to modify both your app.config and web.config, but don't get confused which one you are working on! The simplest way to configure the client is to use the "Add Web Reference" and point to the URL on the server machine. Remember that WCF allows you to configure multiple end points for the same service (an end point is a URL with a port and service name), and each endpoint can have one of many different protocols (I use basicHttpBinding, wsHttpBinding, or netTcpBinding, depending on my needs). I suggest starting with wsHttpBinding, which is one of the easiest to debug. Modifying the app.config or web.config by hand is going to get you in trouble, because one mistype and you're debugging for hours. Stick to the editor.
e) You will not find a good reference on both Prism and WCF, because one does not affect the implementation of the other. By encapsulating your WCF service code inside of a service class served up in Prism by the container, you remove any dependencies between Prism itself and the services, and don't cause yourself headaches later on by inadvertently coupling them together. Later, you can inject your view models with a Moq service class that doesn't make calls to the actual service for testing purposes. Prism has a very good CHM file that has all you need to know about Prism, WCF has great documentation on Microsoft's web site (no book required, unless you want to get fancy, like with that Windows Service).
Feel free to follow up.
Follow up #1:
As I use IIS to host my services, I haven't the experience to guide you on implementing a ServiceHost for multiple services. However, IIS allows putting multiple services into the same application pool (which is basically a single instance of W3WP.exe running on your machine), so I am pretty sure it can be done.
Edit: After reading the WCF Guidance for WPF you provided, I can see that you create one ServiceHost instance inside your EXE for each service you want to host. So you'll need 6 ServiceHost instances, and manage them separately in the EXE code.
Factoring your services is a matter of design. You chose to have one service per domain class. If I did that in my application, there'd be over 100 services. Instead, I chose a to implement a command pattern which allow me to make requests for the objects I want, regardless of type, and it returns them to me in one, clean interface.
I am confident you will not find guidance on accomplishing your design between Prism and WCF in any book. You may find some in blogs, however, here is what I suggest:
Encapsulate your WCF service creation and operations inside of a class (e.g. DataAccessService) that can be injected into your view models through dependency injection (see ImportingConstructor attribute). Use the eventaggregator service to publish events from your DataAccessService if errors (or other notifiable events) occur, and handle them in your view model. Don't create cohesion between your view models or views and the WCF services by calling between them directly, as that will violate both SRP as well as prevent the ability to test the view models without touching your web services (an external dependency).
a) For the "if": sure, why not? For the "how": Write different modules that deploy your services to IIS or Windows Services or Console Hosts and let the user choose which one to run.
b) One Service per host but multiple endpoints with different bindings are possible.
c) In process means that they start when you start your application? Then I would go for the bootstrapper.
d) There is nothing simple about configuring WCF via app.config. The tooling in Visual Studio is puny and the number of knobs and dials is legion. Using code for configuration at least gives you Intellisense support.
e) I don't think that this is a very common combination so I would not bet that there is any literature out there. But for any questions regarding WCF I would recommend reading Programming WCF Services by Juval Lowy. I think the code samples also contain a WinFormsHost for WCF service which might be another option for your "where do I host services" problem.
Related
I have created a windows service which consumes a WCF Service hosted at some location.
The WCF service endpoint is specified in app.config of this windows service.
I am not sure whether what i want is really the right understanding i have about services or not.
So here i go.
I have created a wix installer which encapsulates all my dependent third party dll's into one installer.
Now, the question is do i have to copy all the xsd files the client folder?
If yes , then does changing the WCF endpoint in app.config later once installed , would the new-endpoint be readily adopted by the windows service ( obviously as long as the contract remains same ) or even if it changes.?
I am not able to phrase the question well, maybe that's why even enough of googling didn't bring me any answers.
Please guide me understand this.
The .xsd files need to be copied if your service/dlls make use of them at runtime. I would assume this is the case since it's not likely (although it is certainly possible) that the .xsd files are only used in the development environment. If you have any questions about this, you can always try to install the service on another system and see if it runs successfully without them. Trial-and-error is not the most efficient way to test software, but it works 100% of the time.
As for modifying the endpoint in the app.config post-deployment, the WCF service hosted by your Windows service will happily adopt this providing that you restart the service. This is one of the most appealing features of WCF, namely that how you connect (TCP, HTTP, P2P, etc.) and where you connect (endpoint) can be specified without having to change the code. If the contract changes, things get more sticky. Additions to the contract, e.g., new methods, would presumably be non-breaking changes, but modifications to existing methods would require the code to be rebuilt and redeployed.
HTH
I am relatively green with C# and WCF. I have landed on a project where I am creating self hosted WCF services running as Windows services but am starting to wonder if I should use IIS instead (which we don't currently use) as managing all of these services could eventually get cumbersome.
Despite my best efforts, I have yet to find any definitive information about why I might favor one approach over the other. The services are primarily used for utility stuff like resizing images, retrieving files, etc. and are called by both C# and Java clients.
Thanks
The shortest answer would be 'it depends'. On your requirements. You can self host without problems, but IIS will manage resources more effectively and enable you to fine tune stuff more easily than self-hosted.
For instance, in IIS would be more simple to deploy a new version or remove and old one.
Either way is fine.
Generally, using the builtin IIS hosting capabilities can make deployment and configuration simpler for you. Also you have the activation model of http.sys - which means IIS will start the necessary process for you when an appropriate message arrives.
Clients of any platform can connect to the WCF services regardless whether they are self-hosted or IIS hosted.
ps: how to allow IIS-hosted WCF services to store their configuration data in distinct xxx.config files
I use wcf test client for testing my wcf services, but it has some shortages. Is there an alternative for WCF Test Client application with better Facilities?
Yes there is better application with much bigger feature set called SoapUI but it is not integrated with Visual Studio and its bigger feature set expect that you understand web services. SoapUI is probably leading tool for testing web services and it has free edition but it is not related to MS technologies and because of that it probably doesn't support WCF only features (like duplex, net.tcp, etc.)
Anyway if you want to have testing tool for your service there is nothing more easier then creating test (MS test, NUnit or any other framework) and simply use a proxy to test your deployed service.
I am using WCF Storm which let me save big methods with a lot of parameters in XML. So I can easily load them back later by simply copy-pasting it back. But, the software (at the current stage 2.5.0) lacks of finish... shorcuts are something counter intuitive and recursive cause sometime problem. Still, it's a great application that offer more than the default Wcf Test Client.
Based on your comments i suggest using an unit testing framework such as MSTest or NUnit
In your tests you can setup instances of your service as you would normally, then call them as you would in your production code and verify the results.
Note also that you dont have to launch a whole service host to do this, you can simply make an instance of the class that is implementing your service contract and call it directly. there are some differences to doing this and hosting the service (when hosting, arguments are always serialized, that is, they are passed by value, not by reference) but it usually doesnt matter.
I need to change some configuration settings on-the-fly in a Windows Azure project - and they need to be changed via a web service call (updating the application's configuration either via the platform api or the Azure Management site isn't an option here).
The project has multiple web and worker roles - all of which will need to know about the new configuration when it is changed.
The configuration is persisted to durable storage, and it's also cached during runtime in a static variable.
My solution was to create an internal (tcp) endpoint on my roles, and use that to loop through all of the roles and instances within those roles, create a client on the fly, and tell the instance about the new setting. (pretty much identical to: http://msdn.microsoft.com/en-us/gg457891)
At first I started a ServiceHost in the WebRole's RoleEntryPoint... and I was confused why everything seemed to be working fine when I stepped through the communications (the static variables where getting set correctly) - yet when I'd make other webservice calls, the static variable seemed to have "forgotten" what I set it to.
This was the case both locally, and in the Azure staging environment.
At this point I realized that because we're using full-IIS mode, the RoleEntryPoint and the Web Services were running in two separate processes - one in Azure's stub, and one in IIS.
"Not a problem" I said, I'll simply move the line of code which starts the ServiceHost from my RoleEntryPoint into the global.asax - at which point the ServiceHost will have been started in the same process as the rest of the site - and the static variables would be the same ones.
Here's where I'm having a problem; This works great on my local machine running in the dev environment. As soon as I deploy to staging I start getting error emails saying the channel used to connect to the service can't be closed because it's in a "faulted state".
Question:
What's different about Azure vs. Dev environment that is causing this?
How can I fix or workaround the problem?
Does anyone have any general advice on how I should go about obtaining a more descriptive error... do I have to enable full wcf diagnostics in Azure to get this, or is there some other way I can get at the exception details?
Follow-Up:
Via remote desktop i've learned several interesting things:
Non-HTTP Activation isn't installed by default on Azure WebRoles. I believe this can be overcome via a startup script:
start /w pkgmgr /iu:WCF-NonHTTP-Activation;
The website created in IIS by the web role doesn't have the net.tcp protocol enabled by default. I also believe this can be overcome with a startup script:
%systemroot%\system32\inetsrv\appcmd.exe set app "Website Name Here" /enabledProtocols:https,http,net.tcp
I haven't had time to take this all the way, as deadlines have forced me to implement some workarounds temporarily.
Some useful links related to this topic:
http://msdn.microsoft.com/en-us/magazine/cc163357.aspx
http://forums.iis.net/t/1160443.aspx
http://msdn.microsoft.com/en-us/library/ms731053.aspx
http://labs.episerver.com/en/Blogs/Paul-Smith/Dates/2008/6/Hosting-non-HTTP-based-WCF-applications-in-IIS7/
UPDATE (6/27/2011):
Amazingly, someone at Microsoft (whose blog I commented on) actually got me an answer on this.
The Azure & WCF teams updated this post:
http://blogs.msdn.com/b/windowsazure/archive/2011/06/27/hosting-services-with-was-and-iis-on-windows-azure.aspx
The link contains all of the information you need to get going with this.
And a HUGE thanks goes to Yavor Georgiev, the MSFT PM with the win.
It's been quite a while since I've asked the question, and no answers, so let me leave this:
Per my follow-ups in the post, there are ways of making this work... but they are complicated and difficult to implement.
For WORKER ROLES, netTcpBinding works perfectly. No issues here. Go ahead and use it.
For WEB ROLES, you've got problems.But netTcpBinding is what you need to use for exposing internal endpoints. What to do?
Well, here's what I did:
Start netTcpBinding service in your RoleEntryPoint using ServiceHost.
Create standard WCF service in your web role using SOAP / JSON / Whatever you want.
When you receive requests through your netTcpBinding, proxy them along to the WCF service on the loopback adapter.
Properly secure your "internal" WCF service with SSL client certs.
It's not perfect... but it works, and it's not terrible.
I suspect that needing to do this kind of thing isn't super common, and I really can't think of any reason why you'd need to other than to dynamically modify settings at runtime... which means you're not slamming these services like crazy.
Obviously, YMMV.
I had a miserable time getting HTTP working between instances in staging, and gave up when it looked like I needed to mess around with netsh to give my processes permission to listen via an HttpListener (sheesh!). So I switched to TCP via sockets. HTTP just adds overhead in a point-to-point communication scenario like this.
I have an application that manages the heavy processing for my project, and need to convert it to a "Windows Service." I need to allow running multiple versions instances of the application processing, which seems to be a fairly normal requirement.
I can see at least three approaches to do this:
Create a single installed directory (EXE, DLLs, config) but install as multiple Services instances from it.
Have a single Services instance spawn multiple instances of itself after launching, a la Apache.
Have a single Services instance spawn multiple threads that work within the same process space.
My intention was approach #1, but I kept tripping over the limitations, both in design and especially documentation for Services:
Are parameters ever passed to OnStart() by the normal Services mechanisms on an unattended system? If so, when/why?
Passing run-time parameters via the ImageKey registry seems a kludge, is there a better mechanism?
I got the app to install/uninstall itself as a pair of services ("XYZ #1", "XYZ #2", ...), using the ImageKey to hand it a command line parameter instance number ("-x 1", "-x 2") but I was missing something. When attempting to start the service, it would fail with "The executable program that this service is configured to run in does not implement the service.
So, the questions:
Is there a concise description of what happens when a service starts, specifically for those situations where the ServiceName is not hard-coded (see Q above).
Has anyone used approach #1 successfully? Any comments?
NOTE: I've side-stepped the problem by using approach #3, so I can't justify much time figuring this out. But I thought someone might have information on how to implement #1 -- or good reasons why it isn't a good idea.
[Edit] I originally had a 4th option (install multiple copies of the application on the hard drive) but I removed it because it just feels, um, hackish. That's why I said "at least three approaches".
However, unless the app is recompiled, it must dynamically set its ServiceName, hence that has the solution to the third bullet/problem above. So, unless an instance needed to alter it's install files, #1 should work fine with N config files in the directory and a registry entry indicating which the instance should use.
Though I can't answer your questions specific to option #1, I can tell you that option #2 worked very well for us. We wanted to create an app domain for each 'child' service to run under and for each of them to use a different configuration file. In our service's config file we stored the app domains to start and the configuration file to use. So for each entry we simply created the app domain, set the configuration file etc and off we went. This separation of configuration allowed us to easily specify the ports and log file locations uniquely for each instance. Of additional benefit to us was that we wrote our 'child service' as a command-line exe and simply called the AppDomain's ExecuteAssembly() on a new thread for each 'child' service. The only 'clunk' in the solution was shutdown, we didn't bother to create a 'good' solution for it.
Update Feb, 2012
Some time ago we started using 'named' services (like SQL Server). I detailed the entire process on my blog in a series "Building a Windows Service – Part 1 through Part 7". They take you through creating a command-line/windows service hybrid complete with self-installation. The following goals where met:
Building a service that can also be used from the console
Proper event logging of service startup/shutdown and other activities
Allowing multiple instances by using command-line arguments
Self installation of service and event log
Proper event logging of service exceptions and errors
Controlling of start-up, shutdown and restart options
Handling custom service commands, power, and session events
Customizing service security and access control
A complete Visual Studio project template is available in the last article of the series Building a Windows Service – Part 7: Finishing touches.
Check this out: Multiple Instance .NET Windows Service
There is option #4 that I'm successfully using in my project aka "named instances".
Every installation of your app has custom name and each installation has its own service. They are completely independent and isolated from each other. MS SQL Server is using this model if you try to install it multiple time on single machine.