In practice, you probably won't use the
Uses attribute very often. Mixins are a good way to extend framework classes (re-motion classes, for example). This works best when the framework classes don't even know that they are extended, when no modification of their source code is necessary. This is in contrast to the first example, where
DessertTopping is extended by telling it to mix in the
FloorWax mixin class.
A much more practical route for extending target classes is the
Extends attribute. Instead of telling the target class to use a mixin, you tell the mixin class that it extends one or more target classes:
The framework code, where the extended
DessertTopping resides, remains unaffected. This is of particular utility if you don't have the source code for the framework. Cluttering framework code with application-specific code is frowned upon by programmers, and rightly so. Therefore, the
Extends attribute is preferable for most cases, even if you DO have the source code for the extended class. Attributing the target class with
Uses CAN be
beneficial, but such cases are fairly rare. Expect to use
Extends much more often.
A mixin can extend multiple target classes, for example
Extends are mutually exclusive for the same mixing
Using instances of mixed classes is not influenced by how you mix them, i.e. the code works without regard to who extends whom. Whether you put a
Uses attribute on the target class or the
Extends attribute on the mixin class does not matter. However, never use BOTH for the same mixing. This is redundant, so re-motion mixins will believe you are confused and made a mistake and throw an exception to bring the mistake to your attention:
The bogus code above will compile and link, but it will result in an exception at run-time, when
ObjectFactory tries to mix and instantiate your broken configuration:
Likewise, it is prohibited to put two or more
Extends attributes with the same arguments on the same class.
Sneak preview on re-motion mixins and duck typing
What makes mixins useful is that you can apply them to an arbitrary number of classes, but this flexibility usually goes out the window if your mixin assumes certain members for overriding. However, as we will see later (in re-motion mixins basics -- duck typing), these classes need not to be related in any way. For example, you could have a totally unrelated
Hamburger class with a method that coincidentally has the name
TasteGood, as found in
Hamburger does not need to share anything with the
DessertTopping class, not even an interface. Since re-motion mixins mixes via .NET reflection features, the mixing will work anyway. This duck typing is a hallmark of more dynamic languages like python or ruby, but re-motion mixins make it easy to use in .NET, too.
You find the sample code for this wiki page in subversion