I haven’t posted for a while because I’ve been working on other stuff, and much of that work has encouraged me to think hard about the concept of the ServiceDescription class, the root of what is called the Description Hierarchy that I posted about previously. The ServiceDescription object, when created, contains everything that is known about a WCF service, and is really all that is required by a ServiceHost to get one up and running. One could, if one wanted, override the ServiceHostBase.CreateDescription method and return a ServiceDescription object that has been created live, right there. Many people do in fact do exactly this, populating a ServiceDescription from information contained in a file, or a database, or obtained from another Web service, for example.
Note: If you do this, make sure to override ApplyConfiguration also to return immediately, disabling configuration files.
Of course, you could go the other way, overriding ApplyConfiguration in order to consume any arbitrary file or configuration system, doing the same thing. Imagine that you serialize an entire ServiceDescription object, and in ApplyConfiguration deserialize it and hand it off to the system. I’m using this thought game to point out that the totality of information necessary to execute a WCF service is **collected** from disparate sources and assimilated and validated into a ServiceDescription object, and then THAT is used to construct a service runtime and execute it (if possible). In the default case, the information lives in:
- Attributes on the WCF service implementation. (ServiceContractAttribute, MessageContractAttribute, DataContractAttribute, ServiceBehaviorAttribute, and so on.)
- The structure of the implementation determined by managed reflection over the structure of the service implementation. (For example, WCF throws exceptions if you try to return two MessageContractAttribute types.)
- “Configuration” values contained in the configuration files, including behaviors and bindings and so on.
In fact, if the WCF implementation didn’t require some attributes on the implementation at runtime, it would be possible to build a system in which you implement an implementation without any attributes at all, and specify a huge amount of precise information in a very large configuration file. Then you could build a UI tool to handle that file more easily (SvcSuperConfigMaster.exe, anyone?) And then you could make that tool handle these configuration tables almost anywhere in a Windows domain — or other domain, for that matter. The only thing you’d need to do at runtime, then, would be to point at an implementation that could be loaded at runtime and then configured from the SuperFile.config.
In .NET 3.0, we did a good job of introducing a relatively straightforward way to both program and “model” — another way of saying “specify” or “describe” — the service and it’s runtime information both in a managed assembly (attributes and structure) and in a description file (configuration file). I once mentioned to some of the product managers how all of this I saw as “metadata”, almost the entire thing. They laughed and said, no, no, no. But I still think I’m right.