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.