locked
Redirecting compile-time binding references to my own assembly for compatibility and serialization RRS feed

  • Question

  • I'm not sure this is the best sub-forum for this question, but I have to start somewhere. If an admin knows of a better one, please, move this thread.

    I have an application (C#, latest .NET) that uses plug-ins in the form of class libraries. The plugins will also store a user configuration to disk (SQL database) in the form of a serialized object. All other modules in my projects use the auto-generated minor assembly versions (i.e., x.y.*.*) so I could track changes during the development process. Now, if one version of the plugin has stored a configuration but then I compile a new build (thus generating a new minor revision number), it refuses to load the configuration since it's been built by the previous "version". So far I have resolved this by using fixed versions for those plugins (i.e., x.y.z.w).

    I don't even know what matters most to me, and what I'll need in the future, but (maybe because of exactly that) I'd like to pick the best possible strategy. When the product ships, I would, of course, like to be able to ship updated versions of the plugins, and I'd like them to work with the existing configurations stored by older versions; but also, I'd like to be able to one day issue a new version that is not compatible with the older configurations and I'd like that one to actually refuse to try to load those older configurations.

    I feel like I need to provide a little more detail about the specific use case, because only some scenarios as described above are affected by the problem. There is an abstract base class (and a few others) from which all those plugins are derived. The base class, which is defined in a different assembly, implements a common functionality to retrieve the stored configurations; it also contains other classes from which the serialized object is instantiated. In addition, I don't know if it matters but the call from each individual plugin to retrieve the configurations is made via remoting. That's, apparently, where the check is made, the version mismatch - detected, and the exception - thrown.

    I don't even know if this is an issue of assembly binding or purely about serialization, but I'd appreciate some insights and  recommendations.

    Kamen


    Currently using Visual Studio 2019, native C++ (Windows API) and C# (.NET, WPF), on Windows 10 Pro 64-bit; Mountain Time zone.



    • Edited by Kamen Friday, May 24, 2019 5:12 PM Added details
    Friday, May 24, 2019 4:36 PM

All replies

  • Hi Kamen,

    Thank you for posting here.

    For your question, in a short period of time, updates will be made, but will not be outdated. With the development of technology, this change is unchangeable.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, May 27, 2019 6:17 AM
  • Hi Kamen,

    Thank you for posting here.

    For your question, in a short period of time, updates will be made, but will not be outdated. With the development of technology, this change is unchangeable.

    Best Regards,

    Wendy

    I'm sorry, but I can't even understand if this is an attempt to answer my question or... something else.

    Kamen


    Currently using Visual Studio 2019, native C++ (Windows API) and C# (.NET, WPF), on Windows 10 Pro 64-bit; Mountain Time zone.


    • Edited by Kamen Wednesday, May 29, 2019 4:36 PM
    Tuesday, May 28, 2019 7:59 PM
  • Hi Kamen,

    What I mean is that the library you used would be updated, something maybe be obsolete after a while. Like what you said in your description, you need to update somethings.

    >>I don't know if it matters but the call from each individual plugin to retrieve the configurations is made via remoting.

    It depends on how do you deploy the application. ClickOnce or Windows Installer are a good choice. You could update what you want on your side. And then all the app you deployed would be updated.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, May 29, 2019 6:02 AM
  • Hi Kamen,

    What I mean is that the library you used would be updated, something maybe be obsolete after a while. Like what you said in your description, you need to update somethings.

    >>I don't know if it matters but the call from each individual plugin to retrieve the configurations is made via remoting.

    It depends on how do you deploy the application. ClickOnce or Windows Installer are a good choice. You could update what you want on your side. And then all the app you deployed would be updated.

    Best Regards,

    Wendy

    I'm sorry, Wendy, but I think you're totally misunderstanding my question - it has nothing to do with deployment of an application. It is completely contained in a single build - between two DLL defining a given plugin - the functionality of an abstract method base class and a regular public method of that same class. If the plugin DLL has a different assembly version than the one it had when an object was serialized using the public version of the serialization method of the base class (which is defined in a different assembly), then it would throw the exception, even though there has been no change in the respective code. So: I build the project and save the plugin configuration (serialized object); then build it again, thus the only difference being the assembly version, and then it throws an exception when reading it back in.

    It almost seems like the assembly containing the base class checks for the version of the assembly that uses its derived methods when serializing/deserializing and makes the assumption that it may have changed its content, so it doesn't allow it. I'd lie to control that explicitly. To recap: plugins are derived from a base class that is defined in a different assembly than the one that will produce the plugin DLL and it seems like the former is controlling the assembly version of the latter. I'm trying to figure out what exactly is the problem so I can correct it the proper way.

    Kamen


    Currently using Visual Studio 2019, native C++ (Windows API) and C# (.NET, WPF), on Windows 10 Pro 64-bit; Mountain Time zone.


    • Edited by Kamen Wednesday, May 29, 2019 4:35 PM
    Wednesday, May 29, 2019 4:35 PM
  • Hi Kamen,

    Sorry, I think get what you want now.

    Try to define the version you want to use in Configuration file.

    https://docs.microsoft.com/en-us/dotnet/csharp/versioning

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 3, 2019 2:50 AM
  • Hi Kamen,

    Sorry, I think get what you want now.

    Try to define the version you want to use in Configuration file.

    https://docs.microsoft.com/en-us/dotnet/csharp/versioning

    Best Regards,

    Wendy

    That is not what I want. This article talks about specifying what versions are acceptable, and what - not. It assumes the explicit manual version control that I said I was hoping to avoid. Again: by default I leave the auto-generated version number to update with each build. I just want the base assembly to ignore the version of the derived assembly that was used to serialize the data and not to expect a specific version.

    Kamen


    Currently using Visual Studio 2013 U5, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Monday, June 3, 2019 2:03 PM
  • Hi Kamen,

    Try to right click the reference> Properties> Set the Specific Version to false.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 5, 2019 6:44 AM
  • Hi Kamen,

    Try to right click the reference> Properties> Set the Specific Version to false.

    Best Regards,

    Wendy

    Hi, Wendy,

    I wish it were that simple. The option you describe refers to "static linking" of assemblies. When I wrote about plugins, I assumed it'd become clear that I use reflection to dynamically load those assemblies. Furthermore, for reasons that I have since forgotten, I was forced to take the approach of loading those plugins without context (i.e., using Assembly.LoadFile) and then handle the AssemblyResolve event to find matches in the current context. I guess, this is how dependencies are resolved and I don't remember what exactly was the necessity of that, but someone was helping me and it seemed like the only option, at least at the time (.NET 2.0). I don't know if things have changed and whether it would make any difference, but I'm not about to redesign the entire product just because there may be a better way to do it. I feel like there is something minor that I could do to make this easier. As I said, for now all I'd need to do is control the full version manually; I just wanted to get a better understanding of what the exact reasons for this behavior are, but it may be way too specific to my project. I'll probably leave this until a time when I can devote some more attention into figuring it all out.

    Kamen


    Currently using Visual Studio 2013 U5, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Wednesday, June 5, 2019 5:33 PM