The last part placed our policy assertion in the WSDL:
On the client the WCF evaluates policy assertions during proxy generation, for code and configuration. If you try to import a WSDL containing a policy assertion, the WCF does not know – as is the case with our policy assertion so far – the generated configuration will contain the following warning:
To provide respective import logic the WCF provides an interface IPolicyImportExtension. While this is conceptually similar to what is provided for the export, there is one difference: It is not placed on a binding. In fact, it would not make sense to put it on a binding, as the binding configuration configuration does not yet exist; rather it is part of what is going to be generated during the import. That is why the interface has to be implemented by an arbitrary class, which has then to be announced in the configuration:
During import the WSDL will call respective extensions for all policies it finds. Our job is to check whether the we know the policy assertion. If so, we need to remove it, to prevent the above warning from showing up. Within IPolicyImportExtension.ImportPolicy and it with its parameter of type PolicyConversionContext, this is just one line of code to satisfy the WCF and get rid of the warning:
Now we need to do something with our policy assertion. For our tracking policy I want to place a contract behavior on the generated contract, similar to the service behavior on the server side. This is supported by yet another interface, namely IServiceContractGenerationExtension, and again, on behaviors. So we provide a respective behavior and let our importer add that behavior for the contract. Just one additional line of code:
Still during proxy generation, but some time after our importer has done its job, the WCF will call IServiceContractGenerationExtension.GenerateContract on our behavior. At this time the actual contract interface will have already been created using CodeDOM, so we can party on it and manipulate it as we like. In our case add a contract behavior attribute:
All other methods of the behavior are simply empty. Of course we also need to provide the TrackingContractBehaviorAttribute, also – for the time being – with empty methods.
Note: Strictly speaking, we could use the behavior class. But I want to emphasis the fact that the behavior used to manipulate the code is only present during proxy generation, while the one we just added as attribute is present at runtime.
Running the import again will remove the warning in the configuration. And it will also create a contract amended with our attribute:
In case the policy contains more complex parameters, there is more work to do – analyzing the XML from the policy assertion, generating code with parameters – but the general principle stays the same.
This completes the design time aspects of our policy. The following image depicts the process on server and client (i.e what we covered this post and the last) in overview:
First order of the day fulfilled. The service announces the policy in the WSDL for everyone to take notice and act accordingly. The client proxy generation can be taught to evaluate the policy assertion. What’s important: The bridge between server and client is the WSDL and WS-Policy – common standards, nothing WCF-specific. Similar mechanisms can also be set up on other platforms, e.g. Java with Metro.
The next post will be an addendum, before we take care about the runtime aspects. After all, our implementation doesn’t do anything worthwhile yet.
That’s all for now folks,