Make UnityContainerExtension an interface

Feb 17, 2008 at 3:50 PM
Abstract base classes as interfaces should be a thing from the past.

public interface IUnityContainerExtension
  void Initialize(IExtensionContext context);
greatly simplifies UTs. It also allows easier decoration/composition of extensions. And it allows the extension to derive from something else.
Feb 17, 2008 at 9:25 PM
See "Framework Design Guidelines" by Krzysztof Cwalina, page 77.

Interfaces have serious limitations on versioning, and unless it's going to be an extension AND something else, it doesn't need to be an interface.

I've come to a general rule of thumb that unless the concept you're representing has a name ending in "-able" (like Serializable, Clonable, etc.) you should prefer a base class over an interface.

I didn't experience any unit testing pain due to a lack of an interface when building the container and existing demo extensions. And I'd need to see a real example of decorating/composing extensions before worrying about those scenarios. The composition model is with the strategies and policies added to the container by the extensions, not the individual extensions themselves.

Feb 17, 2008 at 11:33 PM
So it would mean IUnityContainable ? ;)

As for test pain, that's because you've been using handmade mock objects. Some mock frameworks will only dynamically create mock proxies for interfaces or at least it's my favorite thing to get proxied.

public void Add_Extension_Initializes_With_Context()
  IUnityExtension extension = mockFactory.Create<IUnityExtension>();
  UnityContainer container = new UnityContainer();
  //TODO Setup expectation that extension.Initialize will be called.  
  //TODO Verify expectations.

But I agree it wouldn't be my TOP 1 priority to fix.

The main reason I want that is because I wanted to leverage some base class I have in my framework. It defines many properties to be injected (I'd say ILogger and, IExceptionHandler as examples). Having to derive from UnitContainerExtension forces be to define a new Extension base class that will redefine such injected services and that I don't like very much.

From my point of view, base classes should serve as helpers to simplify some key scenarios. Not define a contract that has to be followed.

I'll make sure I review those design guidelines again...
Feb 18, 2008 at 2:40 AM
I've always liked Jeffrey Richter's note on page 83 of Framework Design Guidelines:

"When a class is derived from a base class, I say that the derived class has an IS-A relationship with the base. For example, a FileStream IS-A Stream. However, when a class implementations an interface, I say that the implementing class has a CAN-DO relationship with the interface. For example, a FileStream CAN-DO disposing." - Jeffrey Richter

I like this because it fits in nicely with the IS-A and HAS-A descriptions of inheritence and composition we learn when first introduced to OO principles.

- Derek
Feb 18, 2008 at 3:28 AM
Yeah I remember that quote... CAN-DO is well defined when your interfaces ends with "able" as Chris mentionned.

However, is my LifetimeExtension IS-A "UnityContainerExtension" or CAN-DO "initiliaze the extension context" ? ;)

When defining a contract on a dependency (DIP) (the dependency here from the point of view of the container is the extension interface to initialize a context (policies, strategies) ), I almost ALWAYS define an interface.

I haven't read the guideline extract Chris is talking about and I'm not sure Amazon ships overnight to my hotel room ;) Until then, I feel comfortable to settle down on the fact that it might just be a matter of preference and style.
Feb 18, 2008 at 5:22 PM
I think a better way to ask the question is whether an extension is a noun or a verb. Of course, this speaks more to the ontology of types. The other consideration is how static the contract is going to be. What Chris is concerned with is the ability to change the Extension type in future releases/drops without breaking anything. Both reasons argue for it being an abstract base type rather than an interface. Extensions are both ontologically nouns, and may require additional characteristics over time.

Feb 19, 2008 at 5:07 AM
Yeah it's all great stuff :)

I still haven't read the excerpt... But as I said before, there are "practical" reasons why an interface is better IMHO:

1- Interfaces are easily proxied. It could be for Mock reasons... or for interception (e.g. I want to use VAB + PIAB to do DBC in my extension classes: PIAB doesn't support interception on non-interface, non-marshalbyref types)

2- Not forcing a base classes allows other client bases classes to be used.

But then again, it would have to be prioritized as other issues are way more important than philosophical issues...