0

I am developing a COM class in .net and using it on excel VBA. The requirement is that every excel file should use the version of the class it was developed in. Which should preferably be explicitly stated in the code. So if there is a new version of the class installed, the user would run old macros with the old class and new macros with the new class.

So far I have been renaming the dll and root namespace to Class1 Class2 class3. But this might be causing installation problems. Could the GUIDs be clashing and preventing me from installing them as separate COM objects?

3
  • @ComIntern I thought about it some more, and there is definitely a business requirement for macros developed with a version of the class to run with said version until explicitly upgraded. I cannot expect users of my plugin to unit test them, so I cannot know if or when they will break due to an upgrade. If you know of a way to improve my methods that alings with the requirements, I will be glad to hear it. Commented Aug 29, 2016 at 17:00
  • Say, The old URL checking function was very naive, and users did things like URL = "google.com" . Which might have worked for their purposes. If I add a URL checker that checks for http: or https: I am breaking old code while introducing new functionality. And the original developer might need to revise their code, they might not even be with the company any longer. All of this for almost no gain. The only advantage that I can see is that it would be easier to deploy, I guess. I would like to listen to what your solution to this concrete scenario would be. Commented Aug 29, 2016 at 17:17
  • Converted to answer - cleaning up the comments... Commented Aug 29, 2016 at 17:47

3 Answers 3

1

My proposed solution:

Have every excel macro install their own version of the class.

Have them uninstall it once its done.

Additionally, add a first step where the excel macro uninstalls any leftover versions of the class.

This could be problematic if more than one macro is running at the same time or in a shared computer. So it only works if that is not a requirement.

Sign up to request clarification or add additional context in comments.

Comments

1

The point of having a COM interface is to take versioning out of the equation - if you're actually altering the interface, the usual practice is to add an additional interface to the same object. For example IFoo extends another interface IFoo2 with the first change, IFoo3 with the next change, etc.

In short, if the behavior of the interface changes, then it really should be a new interface. The same logic applies for changes that would break an existing interface. For example, if you have something like...

IFoo.Bar(baz as string)

...and the implementation changes, you would create a new method, using a new interface that extends the old one with that method - i.e.:

public interface IFoo2 : IFoo
{
    void Bar2(string baz);
}

Then document in your change notes that callers should use the newer interface because of the extended functionality. Microsoft did something similar with the *Ex methods in the Windows API, and IIR did the same thing with some of the objects in MS Office.

An alternative is to update your unit tests to account for new calling conventions (assuming that acceptable parameter ranges are changing but the return values aren't changing), and then code to the unit tests. In this scenario, the interface itself wouldn't be changing as long as it still produces the same behavior with the original range of inputs.

2 Comments

My problem with this approach is that my class will be confusing. If a user is presented with URLFunction URLFunction2 and URLFunction3, which one should he use? It also might make the design more complex. Previously I could put all of URLFunction functionality in just 1 function, now it needs to be in 3 different functions. This is even harder if the interface was a class.
@TomasZubiri - That's the downside of publishing a COM interface. I'm sure some of the Windows API code is absolutely torturous to read because they were loathe to break interfaces. Again, the best case scenario is not breaking your existing interface when you make changes.
1

Every time you build, change the GUIDs to something new.

.NET does this automatically if the GUID attribute is not set.

You can then rename the root namespace of each build to include the version. This way you can call a specific version of the class from each excel.

2 Comments

Well, then don't use the [Guid] attribute. .NET auto-generates one that is based on the declaration. Changing the declaration produces a new guid, just like COM requires. Very important however to bump the [AssemblyVersion] so that even a declaration that did not change gets a new guid. Expecting Excel to match a file with an add-in version, well, no.
@HansPassant Thanks! I can make excel files match with the class version's by naming the namespace so that it includes the version

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.