Versioning in .NET


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 9 of 9

Thread: Versioning in .NET

  1. #1
    Willy Van den Driessche Guest

    Versioning in .NET

    I have a real question about .NET versioning. It's going to be a rather
    long question since I don't master the gift of brevity.

    All I hear is that DLL **** is gone now. I can see how it is gone : all
    local components are now no longer register on a per-machine base but are
    rather found in the local directory of the application (and not registered
    at all). Each application ships its own version of the components and no
    application can compromise another application (unless they intentionally
    want to do so). For "global" components there is always the Global Assembly
    Cache (GAC) which allows multiple versions of global components to coexist.
    I can see that this works fine for the majority of applications.

    So far so good. The architecture of our current VB6 application is
    "plug-in-based". Our main application is kind of "dumb". The purpose of
    MainApplication is to host a bunch of "plug-ins" (much like windows explorer
    and shell extensions) There are +40 possible Plugins. Both the Plugins and
    MainApplication are built on top of a SharedToolbox. SharedToolbox contains
    classes and state (singletons) shared between MainApplication and Plugin.

    COM (and especially VB6) makes upgrading a PeaceOfCake (OK, if you know what
    you're doing). I can upgrade any component in my architecture and be sure
    that everything still works as planned.
    P.E. : upgrading SharedToolbox from version 1 to version 2 will not have any
    influence at all on the existing MainApplication and Plugin that where
    previously using Version1. They will start using Version2 without
    questions.
    P.E.2 : upgrading MainApplication from version 1 to version 2 will not be
    allowed if the preconditions are not met. If MainApplicationVersion2 needs
    SharedToolboxVersion3 (because it was compiled with that version) and the
    current installation has SharedToolboxVersion1, then the setup will simply
    fail.
    After an upgrade old and new components work together. VB6 binary
    compatibility (although probably not perfect either) is the stick behind the
    door to keep me from doing stupid things.
    <SideBar> The SharedToolbox actually consists of 8 components. There are 40
    plugins and a MainApplication. If each component is allowed to use its own
    private version of another component, the worst case (without counting
    dependencies between the components in SharedToolbox) would be (40 +1) X 8 =
    328 components loaded in memory (whether they are actually loaded or not is
    quite irrelevant here). To make things worse, my singletons in
    SharedToolbox will "live" for each version of it there is alive in my
    application. A singleton with 41 instances is barely a singleton. This is
    my own perception of the problem <\SideBar>

    Now for the questions :
    1) How would I simulate the behavior of my current APP in .NET ? (If and
    when I switch to .NET it will have to be a pure .NET application. Maybe
    some temporary Interop support but after the Big Bang, no more ActiveX.
    (I'm not switching to a tool which has - for my purposes - a more difficult
    approach to activeX). Would all of my components go into the GAC ? )
    2) If I change a component, how will .NET guarantee me that it will still
    work with old clients (like binary compatibility does in VB6) ?
    --
    For a work in progress :
    http://users.skynet.be/wvdd2/



  2. #2
    Rune Bivrin Guest

    Re: Versioning in .NET

    I'll take a stab at this:

    If your app is based around a plug-in architecture, I would assume that the
    app and the plug-ins communicate through one or more defined interfaces.
    All it takes, then, is creating formal interface definitions and placing
    them in a separate assembly, which you rarely - if ever - touch. This will
    ensure compatibility across versions.

    BTW, this is exactly the same architecture I'd have used in VB 6.0, only
    then I would probably have created an external type library with IDL to
    define the interfaces.

    --
    Rune Bivrin
    - OOP since 1989
    - SQL Server since 1990
    - VB since 1991


  3. #3
    willy Van den Driessche Guest

    Re: Versioning in .NET


    Rune Bivrin <rune@bivrin.com> wrote:
    >I'll take a stab at this:
    >
    >If your app is based around a plug-in architecture, I would assume that

    the
    >app and the plug-ins communicate through one or more defined interfaces.


    >All it takes, then, is creating formal interface definitions and placing


    >them in a separate assembly, which you rarely - if ever - touch. This will


    >ensure compatibility across versions.

    I agree that an interface is a solution. However, it's only half of the
    story. If the interface is something like
    interface iPLugin
    public property get Name as string

    , i.e. a plugin that uses only primitive types this will work. However,
    a plugin needs information from it's "host" be useful. So there will typically
    be at least one method in the interface that passes information from the
    MainApplication to the Plugin, like in

    interface iPLugin2
    public sub Initialize (byval objParams as cSomeTypeDefinedInMainApplicationOrMoreLikelyInSharedToolbox)

    And it's here the trouble begins. Since the Plugin and the MainApplication
    can both be compiled using a different SharedToolbox, there is absolutely
    no guarantee that cSomeTypeDefinedInMainApplicationOrMoreLikelyInSharedToolbox
    as used by the Main Application is compatible in any way with the cSomeTypeDefinedInMainApplicationOrMoreLikelyInSharedToolbox
    as seen by the Plugin.
    I can see some solutions to this :
    1) all parameters of the plugin interface should be passed as Object and
    the plugin has to do the equivalent of "QueryInterface" to see what is passed
    in the parameter. I call this "reinventing COM". COM was created to deal
    with such problems and VB6 even hide all (most at least) of the gory details
    from me. Now I am left to do things manually that where previously done
    automatically.
    2) Use reflection on the parameters (IMHO the equivalent of late binding).
    Allthough VB.NET does a good job at hiding the mechanisms from me, I really
    don't want late binding. Certainly not if it worked with early binding in
    the existing (VB6) version.
    3) Pass generic objects between the boundaries (like XML stuff or DataSets).
    Doesn't sound very OO to me.
    4) Switch to ActiveX in .NET. This is a possibility but a step backward
    since compatibility must be handled manually and since activeX doesn't give
    me the promised easy deployment.
    5) ...

    >
    >BTW, this is exactly the same architecture I'd have used in VB 6.0, only


    >then I would probably have created an external type library with IDL to


    >define the interfaces.

    The interface is define in SharedToolbox. All interfaces (iSomething) are
    threated as immutable (I confess VB6 doesn't help me to keep them immutable).
    In really like VB6's help on upgrading.

    Anyway, having different versions of components around doesn't really solve
    the problem with singletons. Each version will have it's own copy of the
    singleton and in general singletons behave badly in these cases.

    >
    >--
    >Rune Bivrin
    > - OOP since 1989
    > - SQL Server since 1990
    > - VB since 1991
    >

    Thanks for the reply,
    Van den Driessche Willy



  4. #4
    Rune Bivrin Guest

    Re: Versioning in .NET

    "willy Van den Driessche" <willy.van.den.driessche@skynet.be> wrote in
    news:3db009df$1@tnews.web.devx.com:

    > The interface is define in SharedToolbox. All interfaces (iSomething)
    > are threated as immutable (I confess VB6 doesn't help me to keep them
    > immutable).
    > In really like VB6's help on upgrading.
    >
    > Anyway, having different versions of components around doesn't really
    > solve the problem with singletons. Each version will have it's own
    > copy of the singleton and in general singletons behave badly in these
    > cases.
    >
    > Thanks for the reply,
    > Van den Driessche Willy
    >
    >
    >

    You have to keep all interface definitions outside of the operative
    components, and you have to define interfaces for every interaction,
    including callbacks. Do note that it's possible in .NET to include events
    in interface definitions (I haven't tried it, but it's supposed to work).

    As far as the singletons, it's hard to be specific without knowing what
    they do, and why they have to be singletons. Anyway, I'd let the app
    create instances of those components that need to be shared, and then
    maybe put those in a SingletonManager, which could be passed around to
    the plugins. Generally speaking, singletons are a pain in the nether
    regions, but if needed, you're better off managing the singleton-ness of
    them yourself.

    Anyway, the answer lies in interfaces! I think... Right now...


    --
    Rune Bivrin
    - OOP since 1989
    - SQL Server since 1990
    - VB since 1991

  5. #5
    Willy Van den Driessche Guest

    Re: Versioning in .NET

    "Rune Bivrin" <rune@bivrin.com> schreef in bericht
    news:Xns92ABA6F2DAA8Drunebivrincom@209.1.14.29...
    > "willy Van den Driessche" <willy.van.den.driessche@skynet.be> wrote in
    > news:3db009df$1@tnews.web.devx.com:
    >
    > > The interface is define in SharedToolbox. All interfaces (iSomething)
    > > are threated as immutable (I confess VB6 doesn't help me to keep them
    > > immutable).
    > > In really like VB6's help on upgrading.
    > >
    > > Anyway, having different versions of components around doesn't really
    > > solve the problem with singletons. Each version will have it's own
    > > copy of the singleton and in general singletons behave badly in these
    > > cases.
    > >
    > > Thanks for the reply,
    > > Van den Driessche Willy
    > >
    > >
    > >

    > You have to keep all interface definitions outside of the operative
    > components, and you have to define interfaces for every interaction,
    > including callbacks.

    I can see what you're getting at. You want me to define a "typelib"
    assembly. I can see that this will work but it's a lot of work for
    something VB6 does for me automatically. All VB6 objects are approached via
    interfaces automatically. I'll elaborate below...

    > Do note that it's possible in .NET to include events
    > in interface definitions (I haven't tried it, but it's supposed to work).

    I know that. I've tried it and it works. Together with inheritance between
    interface I consider those to be A Good Thing.

    >
    > As far as the singletons, it's hard to be specific without knowing what
    > they do, and why they have to be singletons. Anyway, I'd let the app
    > create instances of those components that need to be shared, and then
    > maybe put those in a SingletonManager, which could be passed around to
    > the plugins. Generally speaking, singletons are a pain in the nether
    > regions, but if needed, you're better off managing the singleton-ness of
    > them yourself.


    My current application has singletons for a lot of stuff. A logContext is
    one of them, a Translator (for multiligual screens ...). I Know .NET has
    it's own implementations of this but that's not really the point. They
    suffer the same problems as my own implementation. I will try to argument
    some more here :
    From the moment you have a componentized application, chances are you have a
    dependency graph between them that contains multiple possible paths from a
    client component to a server (not in a remote sense) component.

    With side-by-side execution inside the same app, you cān get different
    versions of that same server component inside the same app. Singletons
    point to a problem when the server component contains state. However, the
    different versions of the types inside the server component are
    type-incompatible (.NET includes the strong name for type checking). This
    is a worse problem. You can get around all this by creating "immutable"
    assemblies that defie the interfaces and expose all types via these
    interfaces. I call this "implementing COM in .NET". It will work, but VB6
    does a far better job at this. So my response is : side-by-side versions
    inside one app doesn't make sense in this way.

    So one could say : ok, I don't want multiple versions of the same assembly
    inside my app. I just take the latest one. This cān also work but there is
    another problem. There is no guarentee the new version is compatible with
    the previous version. .NET doesn't come with tools to check compatibility
    (like VB6 does).

    So either way, I'm stuck. I remain optmistic into thinking there must be an
    (easy) way out but up to today I haven't found one. You have to know that
    our current APP is 500.000 lines of VB code. The deployment has (once we
    began to understand stuff) always been easy and we now even have an
    "autoupdate" feature. I'm not going to even think about switching it to
    ..NET unless I have a clear understanding of .NET versioning.

    >
    > Anyway, the answer lies in interfaces! I think... Right now...



    >
    >
    > --
    > Rune Bivrin
    > - OOP since 1989
    > - SQL Server since 1990
    > - VB since 1991



    --
    For a work in progress :
    http://users.skynet.be/wvdd2/



  6. #6
    Rune Bivrin Guest

    Re: Versioning in .NET

    "Willy Van den Driessche" <wvddwebcomments@skynet.be> wrote in
    news:3db126d7@tnews.web.devx.com:

    > type checking). This is a worse problem. You can get around all this
    > by creating "immutable" assemblies that defie the interfaces and
    > expose all types via these interfaces. I call this "implementing COM
    > in .NET". It will work, but VB6 does a far better job at this. So my
    > response is : side-by-side versions inside one app doesn't make sense
    > in this way.
    >
    > So one could say : ok, I don't want multiple versions of the same
    > assembly inside my app. I just take the latest one. This cān also
    > work but there is another problem. There is no guarentee the new
    > version is compatible with the previous version. .NET doesn't come
    > with tools to check compatibility (like VB6 does).


    No, you're absolutely right. Side by side execution within the same app
    doesn't make sense. But why would you have that? The app loads whatever
    is present, and works with the interfaces.

    I agree that the work of defining the required interfaces might seem a
    little cumbersome, but once you've done that, you're much more protected
    against formal incompatibilities than VB6 could ever achieve. In VB6,
    there was always the risk of the "expanding interface", where introducing
    a new method in a component would silently create a new interface. You
    would then have to be aware of that, and make sure you always were
    compatible with a good version.

    --
    Rune Bivrin
    - OOP since 1989
    - SQL Server since 1990
    - VB since 1991

  7. #7
    Willy Van den Driessche Guest

    Re: Versioning in .NET



    --
    For a work in progress :
    http://users.skynet.be/wvdd2/
    "Rune Bivrin" <rune@bivrin.com> schreef in bericht
    news:Xns92AC84D6ED675runebivrincom@209.1.14.29...
    > "Willy Van den Driessche" <wvddwebcomments@skynet.be> wrote in
    > news:3db126d7@tnews.web.devx.com:
    >
    > > type checking). This is a worse problem. You can get around all this
    > > by creating "immutable" assemblies that defie the interfaces and
    > > expose all types via these interfaces. I call this "implementing COM
    > > in .NET". It will work, but VB6 does a far better job at this. So my
    > > response is : side-by-side versions inside one app doesn't make sense
    > > in this way.
    > >
    > > So one could say : ok, I don't want multiple versions of the same
    > > assembly inside my app. I just take the latest one. This cān also
    > > work but there is another problem. There is no guarentee the new
    > > version is compatible with the previous version. .NET doesn't come
    > > with tools to check compatibility (like VB6 does).

    >
    > No, you're absolutely right. Side by side execution within the same app
    > doesn't make sense. But why would you have that? The app loads whatever
    > is present, and works with the interfaces.
    >
    > I agree that the work of defining the required interfaces might seem a
    > little cumbersome, but once you've done that, you're much more protected
    > against formal incompatibilities than VB6 could ever achieve. In VB6,
    > there was always the risk of the "expanding interface", where introducing
    > a new method in a component would silently create a new interface. You
    > would then have to be aware of that, and make sure you always were
    > compatible with a good version.


    The expanding interfaces are exactly the feature I like in VB6. When you
    "expand" an interface, VB6 will automatically create a new interface behind
    your back. VB6 will warn you if make an incompatible change but if you stay
    compatible, old clients will still continue to work without recompilation.
    As far as deployment is concerned, the rule is quite simple : never install
    a component if the correct version of the components it was compiled against
    are not installed (I've summarized them in
    http://users.skynet.be/wvdd2/Compili...ment_rules.htm
    l)
    ..NET simply does give the kind of automatic support for change -management
    that VB6 does. Mind you, I'm not blind for the deployment issues of activeX
    components. But these deployment issues could have been solved easily :
    just use a hierarchy of registries instead of one registry. Then finding
    the right components could become a simple chain : search the app registry
    first, then up until you reach the global registry. It would be up to you
    if you register your component in your local app "registry" or somewhere
    else. Each app would see only one version of any given component.
    removing an app would also simply mean deleting the directory since the
    local app registry would be deleted as well and no trash would be left.
    That would finally allow have multiple versions of one app one one and the
    same machine. But I'm dreaming here. Back to .NET

    To silence my critique on .NET I would just need a tool that automatically
    checks for compatibility between two (sets of) assemblies. I only want a
    check for "syntactic" compatibility, since "semantic" compatibility is
    something beyond testability. I have done an attempt at
    http://users.skynet.be/wvdd2/General...lity/_NET_comp
    atibility_checker/_net_compatibility_checker.html but I would really like a
    tool from the "makers" or at least a definition of compatibility for .NET
    assemblies. I don't like relying on "craftsmanship" for this because humans
    do make mistakes. It just strikes me that, while we all agree that the most
    constant thing is change, there are no tools to guide us in making
    compatible changes...

    Thanks for you replies.

    Van den Driessche Willy.



  8. #8
    Patrice Scribe Guest

    Re: Versioning in .NET

    It would seem I saw somewhere that this check is done for you by the
    runtime. When the runtime loads a new version of an assembly it makes sure
    that all the classes have the requested members to avoid breaking the user
    code (actually the current code i.e. deleting a method would not break if
    the method is not used, of course it will break if the client code do use
    this method).

    Try for example :
    http://msdn.microsoft.com/library/de...us/cptutorials
    /html/deploying_versioned_components.asp

    Patrice

    "Willy Van den Driessche" <wvddwebcomments@skynet.be> a écrit dans le
    message de news: 3db177c5@tnews.web.devx.com...
    >
    >
    > --
    > For a work in progress :
    > http://users.skynet.be/wvdd2/
    > "Rune Bivrin" <rune@bivrin.com> schreef in bericht
    > news:Xns92AC84D6ED675runebivrincom@209.1.14.29...
    > > "Willy Van den Driessche" <wvddwebcomments@skynet.be> wrote in
    > > news:3db126d7@tnews.web.devx.com:
    > >
    > > > type checking). This is a worse problem. You can get around all this
    > > > by creating "immutable" assemblies that defie the interfaces and
    > > > expose all types via these interfaces. I call this "implementing COM
    > > > in .NET". It will work, but VB6 does a far better job at this. So my
    > > > response is : side-by-side versions inside one app doesn't make sense
    > > > in this way.
    > > >
    > > > So one could say : ok, I don't want multiple versions of the same
    > > > assembly inside my app. I just take the latest one. This cān also
    > > > work but there is another problem. There is no guarentee the new
    > > > version is compatible with the previous version. .NET doesn't come
    > > > with tools to check compatibility (like VB6 does).

    > >
    > > No, you're absolutely right. Side by side execution within the same app
    > > doesn't make sense. But why would you have that? The app loads whatever
    > > is present, and works with the interfaces.
    > >
    > > I agree that the work of defining the required interfaces might seem a
    > > little cumbersome, but once you've done that, you're much more protected
    > > against formal incompatibilities than VB6 could ever achieve. In VB6,
    > > there was always the risk of the "expanding interface", where

    introducing
    > > a new method in a component would silently create a new interface. You
    > > would then have to be aware of that, and make sure you always were
    > > compatible with a good version.

    >
    > The expanding interfaces are exactly the feature I like in VB6. When you
    > "expand" an interface, VB6 will automatically create a new interface

    behind
    > your back. VB6 will warn you if make an incompatible change but if you

    stay
    > compatible, old clients will still continue to work without recompilation.
    > As far as deployment is concerned, the rule is quite simple : never

    install
    > a component if the correct version of the components it was compiled

    against
    > are not installed (I've summarized them in
    >

    http://users.skynet.be/wvdd2/Compili...ment_rules.htm
    > l)
    > .NET simply does give the kind of automatic support for change -management
    > that VB6 does. Mind you, I'm not blind for the deployment issues of

    activeX
    > components. But these deployment issues could have been solved easily :
    > just use a hierarchy of registries instead of one registry. Then finding
    > the right components could become a simple chain : search the app registry
    > first, then up until you reach the global registry. It would be up to you
    > if you register your component in your local app "registry" or somewhere
    > else. Each app would see only one version of any given component.
    > removing an app would also simply mean deleting the directory since the
    > local app registry would be deleted as well and no trash would be left.
    > That would finally allow have multiple versions of one app one one and the
    > same machine. But I'm dreaming here. Back to .NET
    >
    > To silence my critique on .NET I would just need a tool that automatically
    > checks for compatibility between two (sets of) assemblies. I only want a
    > check for "syntactic" compatibility, since "semantic" compatibility is
    > something beyond testability. I have done an attempt at
    >

    http://users.skynet.be/wvdd2/General...lity/_NET_comp
    > atibility_checker/_net_compatibility_checker.html but I would really like

    a
    > tool from the "makers" or at least a definition of compatibility for .NET
    > assemblies. I don't like relying on "craftsmanship" for this because

    humans
    > do make mistakes. It just strikes me that, while we all agree that the

    most
    > constant thing is change, there are no tools to guide us in making
    > compatible changes...
    >
    > Thanks for you replies.
    >
    > Van den Driessche Willy.
    >
    >




  9. #9
    Willy Van den Driessche Guest

    Re: Versioning in .NET

    > Try for example :
    >

    http://msdn.microsoft.com/library/de...us/cptutorials
    > /html/deploying_versioned_components.asp


    Ok, I'm beginning to see some light here. The URL hints at playing with the
    ..config file. The example they give is a little contrived (?) though. I
    honestly can't see an administrator manually keying in the properties for an
    application. At most the administrator will install the app but for our app
    the administrators will either don't care or will not exist (since we
    deliver a standalone app that is also installed for the butcher around the
    corner).
    So the "publisher policy file" should be my rescue. In there I can
    "redirect" old "clients" to new "servers", which is a large part of what I
    want to do. The good thing is that it is possible. The bad thing is that I
    have to update this file on every deployment and I have a risk of error
    which will be hard to detect. I had a diagonal look at these and they are
    .... new to me. I'll have to sweat some more to grasp their full potentials.

    > It would seem I saw somewhere that this check is done for you by the
    > runtime. When the runtime loads a new version of an assembly it makes sure
    > that all the classes have the requested members to avoid breaking the user
    > code (actually the current code i.e. deleting a method would not break if
    > the method is not used, of course it will break if the client code do use
    > this method).


    The second problem, however still remains. Even when I can upgrade a
    component, I am still left to my own craftsmanship to know whether it is
    compatible. I am not convinced the runtime does a full check on the
    assembly just after loading it. I'm afraid the error will occur when you
    use the first method that is no longer implemented and not before.
    (Reflection makes it impossible to check an assembly up-front). I feared so
    already but I'm beginning to see that there are actually multiple
    "compatibilities" possible between assemblies. It all more or less depends
    on how the assembly gets used. As you point out, in some cases a method
    that gets thrown away might not hurt. However, I am still convinced that
    there is some definable absolute compatibility that holds for all
    assemblies. It can be too strict in some cases but then at least you know
    what you're doing when you're deliberately breaking it. This particular
    compatibility should shout when a public method, interface, class, enum, ...
    gets thrown out. (BTW, the same compatibility constraints apply to
    webservices and other stuff too)

    Thanks to all for the replies. I know where to start.
    --
    For a work in progress :
    http://users.skynet.be/wvdd2/



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center