Coffeehouse Thread

41 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

.Net versioning question

Back to Forum: Coffeehouse
  • User profile image
    cbae

    @BitFlipper: The proxy class generator uses a T4 template, I believe. You should be able to roll your own so you won't have to manually do anything.

    There are a few links to some resources in this thread on Stack Overflow:

    http://stackoverflow.com/questions/1035722/how-can-i-customize-wcf-client-code-generation

     

  • User profile image
    BitFlipper

    @cbae: Hmm that looks interesting. I'd need to take a closer look and figure out how to use it, and whether it would be easier than my last suggested solution.

    For my last solution, it would basically work like this:

    1. Use wsdl.exe to generate the proxy.cs file.
    2. Parse through the proxy.cs file and create a Dictionary<string, string[]> containing each method and its lines of code.
    3. Parse through the proxy.cs file and create a Dictionary<string, string[]> containing each type and its lines of code.
    4. Using the external text file that contains the list of desired methods, create a new proxy.cs file that contains only clases (one for each desired version) with those methods.
    5. Create an interface that has all desired methods. Each proxy class implements this interface.
    6. Based on the list of desired methods, include only those types that appear in those methods' return and arg lists.

    So I will end up with something like:

    public interface Api
    {
        void Foo(SomeClass someClass);
    }
    
    public partial class Api10 : Api, System.Web.Services.Protocols.SoapHttpClientProtocol
    {
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:internalversion123/1.0", RequestNamespace="urn:internalversion123", ResponseNamespace="urn:internalversion123", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public void Foo(SomeClass someClass) {...}
    }
    
    public partial class Api20 : Api, System.Web.Services.Protocols.SoapHttpClientProtocol
    {
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:internalversion123/2.0", RequestNamespace="urn:internalversion123", ResponseNamespace="urn:internalversion123", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public void Foo(SomeClass someClass) {...}
    }
    
    public class SomeClass
    {
        ...
    }
    
    

     

    Edit: And then to use:

    Api api = null;
     
    // One time initialization...
    switch (version)
    {
        case 10:
            api = new Api10();
            break;
    
        case 20:
            api = new Api20();
            break;
    
        default:
            throw new Exception("Unsupported API version");
    }
     
    // Somewhere else...
    api.Foo(someClassInstance);

     

  • User profile image
    cbae

    @BitFlipper: The problem with your code is that if all versions of the Api implement the same interface, you'll have to change the existing interface to accommodate newer versions of the Api by adding methods to the common interface. Because older versions of the Api class won't implement code for any of the new methods of the modified interface, your program won't compile.

    What you can do is create a different interface for each specific version of the Api. In doing so, each interface for a particular version becomes a superset of the interface for the prior version.

    Because of the way C# handles multiple inheritance of interfaces, a single method declaration in a concrete class implements the method declared in EVERY version of the interface as long as the method signature is the same in all of those different interfaces. That means you can declare Api20 as implementing both IApi20 AND IApi10 and you only have to write the method code for Foo() once.

    So if you want to call a method that was declared as part of IApi10, you can cast your Api20 instance (or any future version of the Api for that matter) as IApi10 and it will still call the version of  the method for the instance.

    Try out the program in my prior post (the most recent one with code). It's actually a working console program. It will give you an idea of what I'm talking about.

  • User profile image
    BitFlipper

    , cbae wrote

    @BitFlipper: The problem with your code is that if all versions of the Api implement the same interface, you'll have to change the existing interface to accommodate newer versions of the Api by adding methods to the common interface. Because older versions of the Api class won't implement code for any of the new methods of the modified interface, your program won't compile.

    What you can do is create a different interface for each specific version of the Api. In doing so, each interface for a particular version becomes a superset of the interface for the prior version.

    As I mentioned before, in my case it is not a problem because I'm only interested in a certain subset of methods, and while the new API versions will be adding new methods (and types), I don't care about those. I'm only interested in a core subset of methods that all versions contain. Remember I'm filtering out all methods I don't care about, which would cause each proxy class version to have the exact same set of methods that are available even in the oldest API.

  • User profile image
    cbae

    , BitFlipper wrote

    *snip*

    As I mentioned before, in my case it is not a problem because I'm only interested in a certain subset of methods, and while the new API versions will be adding new methods (and types), I don't care about those. I'm only interested in a core subset of methods that all versions contain. Remember I'm filtering out all methods I don't care about, which would cause each proxy class version to have the exact same set of methods that are available even in the oldest API.

    OIC

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.