re-motion mixins basics -- what about sub-classes of the target class?
Classes derived from the target class "inherit" all mixins from the target class. In section re-motion mixins basics -- the generic 'Mixin' type we will make extensive use of a Parrot
class. Many types of parrots exist – the clever grey parrot, the colorful macaw, the red (marxistic-leninistic?) Cuban parrot. The list in wikipedia goes on and on. Assuming we have a parrot hierarchy with Parrot
as base class, we can mix in a CircusMixin
to teach parrots how to ride the unicycle:
public class Parrot { public virtual void Fly () { Console.WriteLine ("Flapflap..."); } public virtual void Whistle () { Console.WriteLine ("<river kwai march here>"); } public virtual void Say (string s) { Console.WriteLine ("\"{0}\"", s); } } public class GreyParrot : Parrot { public virtual void DestroyFurniture () { Console.WriteLine ("Destroying furniture..."); } } public class Macaw : Parrot { public virtual void CrackNut () { Console.WriteLine ("Cracking nut..."); } } public interface ICircusMixin { void RideUniCycle (); } [Extends (typeof (Parrot))] public class CircusMixin : ICircusMixin { public void RideUniCycle () { Console.WriteLine ("I'm so amazing! I'm riding a unicycle!"); } }
Mixing the CircusMixin
to parrot will mix it to the sub-classes GreyParrot
and Macaw
automatically. Not only the Parrot
, also the GreyParrot
and the Macaw
acquire unicycle-skills:
// Don't forget to touch the API in the library FrameworkVersion.RetrieveFromType (typeof (IMixinTarget)); var myCircusParrot = ObjectFactory.Create<Parrot> (ParamList.Empty); Console.WriteLine ("Parrot:"); myCircusParrot.Whistle (); // do as parrots do ((ICircusMixin) myCircusParrot).RideUniCycle (); // show off what you have learned Console.WriteLine (); Console.WriteLine ("GreyParrot:"); var myCircusGreyParrot = ObjectFactory.Create<GreyParrot> (ParamList.Empty); myCircusGreyParrot.DestroyFurniture (); // grey parrots LOVE destruction ((ICircusMixin) myCircusGreyParrot).RideUniCycle (); // show off what you have learned from your ancestor Console.WriteLine (); Console.WriteLine ("Macaw:"); var myCircusMacaw = ObjectFactory.Create<Macaw> (ParamList.Empty); myCircusMacaw.CrackNut (); // for a macaw, a nut is like a zip-loc; keep hands and feet clear! ((ICircusMixin) myCircusMacaw).RideUniCycle (); // show off what you have learned from your ancestor Console.WriteLine ();
We have used the Extends
attribute for mixing here. Again, it does not matter whether you attribute the mixin class with Extends
or the target class with Uses
– mixing is inheritable up the class hierarchy.
Sample code
The sample code for this example is in https://svn.re-motion.org/svn/Remotion-Contrib/Samples/Mixin/WikiSamples/trunk/WikiSamples.ParrotSubclasses/Program.cs
See also
You can exclude arbitrary subclasses from being mixed. This is an advanced topic and discussed in section advanced re-motion mixins -- removing items, scoping of mixin configurations.