Host View as Interface Instead of Base Class

Jan 13, 2008 at 4:44 PM
The Help Walkthrough creates an base class as the host view. Pipeiline Builder creates an interface. Both are of course valid and perform a very similar thing. But I'm curious as to why the decision to use the interface approach in pipeline buidler.
Jan 14, 2008 at 4:50 PM
Originally we actually used abstract base classes exclusively instead of interfaces but we soon decided to make the switch for a few reasons.

The first is that with many extensibility models we found that it was very desirable for some types to implement more than one "Contract" and this was only possible if the contract was expressed as an interface in the view rather than the base class.

The second reason was because of how events needed to be represented in these view types. The goal was to have events be described very simply in the views and not have to force developers to go through a bunch of generated methods to access them. Originally we represented them on abstract base classes as abstract members that add-in/host developers could simply implement:
public abstract class AppObject
{
     public abstract event EventHandler<FileInfoEventArgs> FileOpened;
}
As it turns out though abstract events are unsupported in VB. When a VB developer tries to implement the above class the abstract event will be invisible to the developer (and even compiler it seems) and they will be able to compile the app without implementing the event. This then causes an exception when the type is actually loaded because it is still has abstract members.

If, on the other hand, we had made it a concrete event on the abstract base class we would have also have had to generate methods that allowed the derived types to actually fire the event (since in C# and other languages only the declaring type, not the inherited type can fire an event). This was of course possible but we felt let to a sub-par experience for add-in developers in particular.

Moving to interfaces and simply declaring the event on the interface solved both of these issues nicely.


We still support a custom attribute in PipelineHints that will generate an abstract base class in the view rather than an interface, but it isn't supported for types that have events declared on them.
Jan 14, 2008 at 10:02 PM
Thanks for the explanation.

I had decided the change to interface was a really good idea so that I could implement it in a class that already inherited from something else. It's good to understand the other reasons and really great that you thougth through the VB scenario up front. My current project for System.AddIn is in VB (I do both languages) and I'm using VB for the contract, host and add-in. I'm not currently concerned that the generated classes are in C#, although I understand VB output will be available in the future.