...
In
...
practice,
...
you
...
probably
...
won't
...
use
...
the
...
Uses
...
attribute
...
very
...
often.
...
Mixins
...
are
...
a
...
good
...
way
...
to
...
extend
...
framework
...
classes
...
(
...
...
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:
...
Code Block |
---|
[Extends (typeof (DessertTopping))]
public class FloorWaxMixin : IFloorWaxMixin
{
public void SealFloor ()
{
Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
}
}
{code}
|
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
...
Code Block |
---|
[Extends (typeof (DessertTopping))]
[Extends (typeof (IceCream))]
[Extends (typeof (Pudding))]
public class FloorWaxMixin : IFloorWaxMixin
{
public void SealFloor ()
{
Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
}
}
{code}
h5. {{Uses}} and {{Extends}} are mutually exclusive for the same mixing
_Using_ instances of mixed classes is not influenced by how you mix them, |
Uses
and 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:
...
Code Block |
---|
// *** THIS IS WRONG SAMPLE CODE ***
[Uses (typeof (FloorWaxMixin))]
public class DessertWax
{
public void TasteGood ()
{
Console.WriteLine ("Mmmmmm, tastes terrific!");
}
}
// *** Either use 'Uses' or 'Extends'; using BOTH is a mistake
[Extends (typeof (DessertTopping))]
public class FloorWaxMixin : IFloorWaxMixin
{
public void SealFloor ()
{
Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
}
}
{code}
|
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:
...
Code Block |
---|
Two instances of mixin DessertWax.Uses.FloorWaxMixin are configured for target type DessertWax.Uses.DessertTopping.
{code}
|
Likewise,
...
it
...
is
...
prohibited
...
to
...
put
...
two
...
or
...
more
...
Uses
...
or
...
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
...
...
...
...
...
...
...
),
...
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
...
DessertTopping
...
.
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.
Sample Code
You find the sample code for this wiki page in subversion