I'm new to WCF, so I opened up 2 projects: WCF class library and a host console application.
Now, both projects have app.config to store the WCF service configuration settings.
As it seems to me now, and correct me if I'm wrong, I have redundancy in configuring both projects with WCF settings.
How is it done in real world production software ? Does it use separate *.dll library for WCF services, or is it implemented withing the host project (and by that use a single place configuration of it) ?
Thank you .
EliorCohen's answer is correct, but I wanted to expand on a couple of points.
First, your building a WCF class library - library's don't use configuration files on their own. They use the configuration file of the calling application. This is something that I've seen cause a lot of confusion for developers, especially if they create a new class library and they see an App.config file in the project.
Second, with WCF 4 you can actually host a service without specifying anything in the configuration file. The runtime will add default endpoints based on the URI's supplied when you construct the service host.
You can also use set up default bindings and behaviors that will override the normal defaults - for example, if all of your services would be handling large requests, you might want to define a default binding with larger values (by ommitting the name attribute in the Binding configuration).
WCF is wonderful in that it has a lot of options - but that blessing is also a curse at times, especially when you first start working with it.
For more information on default endpoints and stuff, see A Developer's Introduction to Windows Communication Foundation 4.
Note that you'll still need a configuration file for any client apps.
the wcf project you are building represent an implementation of the service.
the configuration need to be on the host of the service (your host app).
Related
First please tell me is this solution structure is good as far as Architecture is concern?
I have XXXX. Business project in center.
XXXX. Contract project has a reference of it.
XXXX. Service project has reference of Contract and Business project.
Now i want my service to be hosted on flexible environments. That's why I want to put custom hosting logic in the Service > Host folder. This project will also have Custom Instance providing facility so that My service classes can be created with some parametric constructor.
Also I need to have different kind of endpoints so I also have a folder for Bindings
These 3 custom things currently suffice my requirement.
Now please guide me with some sample code snippet for Bindings/Host/Instance
I do not know what you mean by
i want my service to be hosted on flexible environments
and
I want to put custom hosting logic in the Service > Host folder
The type of hosting container used depends on the type of project (web, console, windows service, etc) which the service implementation is reference in. This is not something you want to bundle into one project, you should have a different project (or even a different solution) for each of your different service instances.
And this leads to your general solution structure. By placing the contracts as a project in your solution, you are coupling the contract assembly build (and potentially, deployment) to the build and deployment of your solution. The contracts should ideally be in their own solution so that they can be built and managed separately from your service implementation. What if at some time you need to maintain multiple versions of your contracts?
I think your approach to create a generic service which can be anything to anyone is way to complex. You should let WCF take care of this kind of work for you, create a different project at least for each of your service implementations, and defer the bindings management to deploy-time.
Additionally, unless you are writing your own custom bindings code you will not require a folder for bindings.
Bindings can (and should) be defined in configuration when you ship your endpoint, and to some extent, the decision about which transport binding to use should be an administration or management rather than a development concern.
We have a set of WCF services that use to MSMQ. We use the static web.config file to indicate to the services where the MSMQ host is.
Moving to AWS, we now need to dynamically specify the MSMQ host address. We figure we can pick between 2 options:
1) Write a script to update the web.config files when spinning up the AWS instances.
2) Drop the config files and implement a helper function that will resolve the MSMQ host address at runtime.
Anyone has any insight on what approach would be better or be considered best practice?
Thanks!
We ended up using solution #1.
This was a trivial script to write and now we can use environment variables anywhere in our web.config files (not just to set the MSMQ endpoints).
Keeping the MSMQ config in the web.config files also allows us to change queue technology if/when needed by using other bindings (ex: RabbitMQ) with no changes to the source code.
In article after article after article, any discussion of using an IOC Container (Unity, Windsor, etc.) with IIS involves the creation of a custom ServiceHostFactory and a custom ServiceHost.
The only reason I can see for that, is so that a custom service behavior, with an IInstanceProvider-related payload, can be applied to all services. So I'm trying to understand why the whole affair is not simplified by having an anonymous service configuration. Such configuration would allow a custom behavior to be applied to all services without using a custom ServiceHostFactory and custom Service Host.
That said, the only reason I can imagine a custom service host would be necessary is if the custom IInstanceProvider is recycled with each WCF instance or context instance. Certainly I would want IOC Container bindings to be established only once for each launch of my IIS ServiceHost rather than repeatedly or irregularly.
If my custom IInstanceProvider is indeed being recycled sporadically, then I could put my IOC Container into a custom service host - to insure that it will stick around as long as possible.
But again, if my custom IInstanceProvider will last as long as the in-built service host, then why not just skip the custom service host factory and custom service host?
In fact, taking this a bit further, if I were to put my IOC Container into a static member of my custom IInstanceProvider, then it wouldn't matter if the IInstanceProvider was being recycled irregularly. It comes full-circle: why do I need or want a custom ServiceHostFactory and custom ServiceHost to use an IOC Container with WCF?
Well. That's because most IoC/WCF integrations (like mine) does more than just creating your service (with it's dependencies).
Custom lifetimes / Disposal
Everything should get clean up properly when a request have ended. Your servcice and your IoC classes uses different lifetimes.
The end of a request can't be detected just with the help of an InstanceProvider.
IContractBehavior / IServiceBehavior
You can register behaviors in the container and automatically get them added to your WCF service.
Personally, i'm a fan of using a design where you don't need any ServiceHostFactory, ServiceHost, ServiceBehavior, and InstanceProvider combination and where you don't have to register the factory in your .svc file. I like my WCF service as just a really thin layer on top of a message passing architecture, and this saves you from using this WCF integration stuff. You can read more about such a design here.
Interesting question! The only reason I could think of for doing it this way is that you don't want to clutter up your app.config with items that are never going to change (i.e. the IoC container used by your WCF services). I try to restrict my use of the app.config to things that an end-user / developer might conceivably want to change without recompiling (in most cases, not much). This makes it more readable, and it is usually easier to specify configuration programmatically as there is better support for intellisense and compile-time checking within program code as opposed to configuration files.
However, this argument might not apply to the first article you linked to, because they're actually setting up their IoC container through the app.config. So it might be a double standard in this case. I've never really understood why people want to set up all their dependencies through external configuration files anyway. Storing static configuration in the app.config just seems like overkill to me in most cases.
We have an EPOS system that is built in VB6. A client is using Microsoft Dynamics AX as a CRM system. A 3rd party has created the AX implementation for our client and they've exposed a set of WCF web services that we need to consume to synchronise data between the EPOS and the AX CRM. Knowing VB6 would have issues calling WCF services, I created the following components to handle the communication between the EPOS and the AX CRM.
VB6 EPOS which calls -->
1) VB6 DLL wrapper which calls... -->
2) .NET(3.5) COM Callable Proxy DLL wrapper which calls... -->
3) .NET(3.5) Web Service Handler (Where the web servicesw actually get called) -->
Microsoft Dynamics AX CRM.
I built a test console app in Vb.NET to simulate calls from VB6 to help with debugging, so that test console app calls component 2.
Whilst doing this I was getting the following exception:-
"(could not find default endpoint element that references contract 'X' in the servicemodel client configuration section. this might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.)"
I googled around and found that I had to copy the bindings and endpoints section from Component 3's app.config to a new app.config for my Test Console app. I don't know WCF and haven't got the time at the moment, to really learn it to the point where I understand why this fixed this error.
Now though, I'm trying to call the services from the VB6 EPOS and this error is popping up again. So I added an app.config to Component 2, thinking that as Component 2 is the first .NET(3.5) component in the chain, that is where the endpoint declaration should go, but No. The error is still popping up.
Does anyone have any ideas? Any programming heroes out there that can shed some light on this for a simpleton please??? Please don't ask why we don't re-write the EPOS. We will. just not yet. Theres over 3 million lines of spaghetti code in there and I've only been working on it for 8 months!!!
As an aside, Doesn't this scenario break one of the golden rules of OOP, i.e. encapsulation. Why should my VB6 EPOS need to know what endpoints Component 3 uses to access the WCF service???
Great question here...
Your problem is essentially coming from all the required configuration data needed to work with a WCF Service.
When dealing with .NET Windows or Web Applications the configuration data on both the client and server sides of WCF Services reside in the application configuration file. For a windows application this file will be app.config, whereas it will be a web.config for a web application.
In your case, you would like to put the proxy logic in some form of a COM-visible .dll.
This is going to cause you some grief...in the .NET platform, the .config file for top-level host application (web or windows) is the place where all configuration data is read. Even if your application leverages dozens of .NET assemblies (each with custom configuration needs), the runtime is going to expect those configuration elements to all reside in the top-most application configuration file.
To resolve your issue, you are going to need to communicate to a service that VB6 does have access to (think ASMX web services) and have that service forward your call along to the appropriate WCF service.
The other alternative is to pass configuration variables directly from your VB6 application to your Com-visible assembly so you can use the extensibility model of WCF to create proxies (overriding the default behavior to read configuration data from a file) with your passed-in configuration.
I would say that the latter scenario could go both ways as far as being a violation of SOA/OOP..depending on the situation it may/may not be appropriate for the VB6 application to know about/store configuration details for communicating with the (eventual) WCF endpoint
We are moving a WPF app across to use WCF and POCO. So far there are 10 or so services, but this will grow with time. It seems to me that we are having to repeat a lot of rubbish (the same text, I know its not rubbish) in the app.config to wire up the services for WCF.
It seems to me to be a nice place to work with convention over configuration. If I put what the defaults would be in a config section and listed / integrated what the services are it could wire them up when the application fires up.
It feels like this would also make deployments easier as there would only be one or two lines to change (addresses etc).
Is there any framework out there (did a bit of Googling and didn't find anything) that does this sort of thing? If not, is it because this is a daft idea or not practical to implement?
I am reasonably new to WCF so there could be issues that I am not aware of at this point.
Thanks for any and all advice around this subject.
.NET 4 cleans up the config quite nicely, and WCF 4 in .NET 4 also has lots of sensible "defaults" - you might not even need any additional config files, with the default endpoints (one for each service contract implemented by your service class, and for each defined base address in your config / service host) and so forth in WCF 4.
Read all about the new features in WCF 4 here:
A Developer's Introduction to Windows Communication Foundation 4
Read, digest, enjoy! :-)