Cannot create abstract ExcelRibbon

Nov 30, 2011 at 3:35 PM
Edited Nov 30, 2011 at 3:36 PM

Hi,

I have a specific use case where I have two ExcelDNA addins that share common functionality. My technique thus far has been to create abstract base classes in a common dll, which are then extended by each addin separately. This works great for abstract implementations of IRtdServer and IExcelAddin (because they are just interfaces). However the ExcelRibbon class resists this paradigm because of the following code in AssemblyLoader.cs (line 149):

bool isRibbon = (t.BaseType == typeof(ExcelRibbon));

My AbstractRibbon class passes this test, but the concrete subclass does not because its "BaseType" is AbstractRibbon, not ExcelRibbon.

Can I suggest this be changed to:

bool isRibbon = t.IsSubclassOf(typeof(ExcelRibbon));

This seems more reasonable to me since it really should not matter whether a ribbon directly extends ExcelRibbon or not. If we want to be even more thorough, we can add:

bool isRibbon = t.IsSubclassOf(typeof(ExcelRibbon)) && !t.IsAbstract;

(This way we avoid the exception when invoking Activator.CreateInstance(t) on line 159).

Hope this is helpful in creating a more robust framework!

Thanks,

Ismail Degani

Coordinator
Dec 4, 2011 at 7:54 PM

The problem I faced is that a concrete class that derives from ExcelRibbon might have further concrete subclasses (which the type checker will only find later). So I can't easily check check whether a class is a most-derived class that is a subclass of ExcelRibbon. This causes me to load the Ribbon more than once, leading to a mess. Maybe I can load for the first non-abstract class that derives from ExcelRibbon?

-Govert

Dec 21, 2011 at 11:12 PM

Hi Govert,

Thanks for the response - I didn't realize only one "ExcelRibbon" class could be created.

In this case, yes, I think the first non-abstract class should be loaded. (Or maybe if a user has multiple, he could specify which he wants in the dna file?)

Thanks!

Ismail

Coordinator
Dec 22, 2011 at 8:00 AM

Hi Ismail,

It's not that only one ExcelRibbon class can be created - you can have multiple ribbon classes as long as you deal with the GetCustomUI for the ribbons separately. 

The issue is that we don't want to instantiate different instances of the same inheritance hierarchy - id class A derives from ExcelRibbon and B derives from A, we just don't want to instantiate both A and B.

Adding some special directive in the .dna file sounds like a step too far, but the other change should be easy to make.

-Govert

Coordinator
Jan 8, 2012 at 9:41 PM

Hi Ismail,

OK, I have implemented this in the latest check-in  - Change Set 71779 under the Source Code tab.

 

The behaviour is now: 

A class is instantiated as a ribbon handler if it is a descendent of ExcelRibbon and is the least derived non-abstract class. So you can add some abstract base classes which derive from ExcelRibbon, and the first non-abstract derived class will be used. Going all the way to find the most-derived classes would be possible but a bit tricky to change in the code. This seemed like a good compromise.

 

Could you please check that the new version works for you, and that this issue is resolved for you?

-Govert