Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

We

...

can

...

make

...

Chevy

...

Chase'

...

New

...

Shimmer

...

skit

...

even

...

more

...

funny

...

by

...

adding

...

a

...

shaving

...

cream

...

to

...

the

...

mix,

...

giving

...

our

...

civilization

...

a

...

shaving

...

dessert

...

wax:

...

}
Code Block
public interface IShavingCreamMixin
{
  void LubricateBeardStubbles ();
}

[Extends (typeof (DessertTopping))]
public class ShavingCreamMixin : IShavingCreamMixin
{
  public void LubricateBeardStubbles ()
  {
    Console.WriteLine ("For a close, smooth shave with no side-effects!");
  }
}
{code}

And,

...

as

...

already

...

mentioned

...

in

...

re-motion

...

mixins

...

basics

...

--

...

the

...

'Extends'

...

attribute

...

,

...

it

...

does

...

not

...

end

...

there:

...

our

...

application

...

can

...

mixin

...

super

...

glue,

...

vitamins

...

even

...

extra

...

calcium!

...

The

...

problem

...

is

...

that

...

you

...

have

...

to

...

cast

...

to

...

an

...

interface

...

for

...

the

...

members

...

of

...

each

...

mixin

...

class.

...

This

...

leads

...

to

...

excessive

...

typing.

...

Enter

...

the

...

finger-friendly

...

attribute

...

CompleteInterface

...

.

...

You

...

combine

...

the

...

interfaces

...

for

...

all

...

mixins

...

and

...

an

...

interface

...

for

...

the

...

target

...

class

...

with

...

multiple

...

inheritance

...

and

...

attribute

...

that

...

super

...

interface

...

with

...


CompleteInterface

...

:

...

}
Code Block
// ***** This code is just for illustration, not part of this sample *****
[CompleteInterface (typeof (DessertTopping))]
public interface IUniversalWax: IDessertTopping, IFloorWaxMixin, IShavingCreamMixin, IVitaminsMixin, ICalciumMixin, AromaTherapyMixin { }
{code} 

Then you pass that interface to the {{ObjectFactory}}; out comes and instance that sports all members from all mixin classes and the target class natively -- no casts required. 

For brevity, we will demonstrate the {{CompleteInterface}} attribute for the components implementing 
- {{IDessertTopping}} (we introduce an interface for the target class here), 
- {{IFloorWaxMixin}} (already introduced in previous sections)
- {{IShavingCreamMixin}} (listed above)

In practice, you can combine as many interfaces as you need.

{code}

Then you pass that interface to the ObjectFactory; out comes and instance that sports all members from all mixin classes and the target class natively – no casts required.

For brevity, we will demonstrate the CompleteInterface attribute for the components implementing

  • IDessertTopping (we introduce an interface for the target class here),
  • IFloorWaxMixin (already introduced in previous sections)
  • IShavingCreamMixin (listed above)

In practice, you can combine as many interfaces as you need.

Code Block
// NOW we need an interface for the 'DessertTopping' target class
public interface IDessertTopping
{
  void TasteGood ();
}

// 'DessertTopping' implements 'IDessertTopping'
public class DessertTopping : IDessertTopping
{
  public void TasteGood ()
  {
    Console.WriteLine ("Mmmmmm, tastes terrific!");
  }
}

// You know that one already
public interface IFloorWaxMixin
{
  void SealFloor ();
}

// Nothing new here
[Extends (typeof (DessertTopping))]
public class FloorWaxMixin : IFloorWaxMixin
{
  public void SealFloor ()
  {
    Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
  }
}

// As shown in the previous listing
public interface IShavingCreamMixin
{
  void LubricateBeardStubbles ();
}

Extends (typeof (DessertTopping))]
public class ShavingCreamMixin : IShavingCreamMixin
{
  public void LubricateBeardStubbles ()
  {
    Console.WriteLine ("For a close, smooth shave with no side-effects!");
  }
}
{code}

Now

...

you

...

can

...

tell

...

the

...

ObjectFactory

...

that

...

a

...

new

...

interface,

...

IShavingDessertWax

...

combines

...

all

...

the

...

interfaces

...

required

...

for

...

a

...

shaving

...

dessert

...

wax

...

instance,

...

and

...

that

...

this

...

interface

...

and

...

the

...

implementations

...

for

...

its

...

various

...

components

...

together

...

implement

...

the

...

extended

...

DessertTopping

...

target

...

class:

...

}
Code Block
// Enter the 'CompleteInterface' attribute
[CompleteInterface (typeof (DessertTopping))]
public interface IShavingDessertWax : IDessertTopping, IFloorWaxMixin, IShavingCreamMixin { }
{code}  

This measure comes with two benefits:
- it makes casting to interfaces obsolete when using various mixed in members in the instance
- it makes instantiation completely abstract, because we pass an interface to {{ObjectFactory}}, not a class

The client code is clean and compact:

{code}

This measure comes with two benefits:

  • it makes casting to interfaces obsolete when using various mixed in members in the instance
  • it makes instantiation completely abstract, because we pass an interface to ObjectFactory, not a class

The client code is clean and compact:

Code Block
 // you must force the .NET runtime to load a reference to the
 // Remotion.dll assembly. Otherwise the compiler will remove the
 // facilities for loading the Remotion.dll assembly and your application
 // will throw a type initializer exception, because it can't load it.
 // The easiest way to touch the assembly is to use the IMixinTarget
 // identifier:
 FrameworkVersion.RetrieveFromType (typeof (IMixinTarget));

// Note that we pass an interface to the factory, the factory knows what
// implements the mixed class from all the attributes we used
var myShavingDessertWax = ObjectFactory.Create<IShavingDessertWax> (ParamList.Empty);

// Now we can save typing, no casts required
myShavingDessertWax.TasteGood (); 
myShavingDessertWax.SealFloor ();                // no cast to 'IFloorWaxMixin'! 
myShavingDessertWax.LubricateBeardStubbles ();   // no cast to 'IShavingCreamMixin'!

Console.ReadLine ();

{code}

h5. {{CompleteInterface}} for inversion of control?

Decoupling an interface from its implementation is an extremely useful strategy for keeping code maintainable and among the first things aspiring software architects learn. So-called 
CompleteInterface for inversion of control?

Decoupling an interface from its implementation is an extremely useful strategy for keeping code maintainable and among the first things aspiring software architects learn. So-called inversion-of-control

...

containers

...

store

...

the

...

knowledge

...

of

...

which

...

implementation

...

should

...

map

...

to

...

which

...

interface,

...

the

...

factory

...

reads

...

in

...

this

...

mapping

...

and

...

returns

...

instances

...

to

...

the

...

application

...

based

...

on

...

this

...

mapping.

...

This

...

design

...

pattern

...

is

...

unrelated

...

to

...

mixins,

...

because

...

it

...

is

...

much

...

broader

...

in

...

scope.

...

You

...

might

...

feel

...

tempted

...

to

...

use

...

re-motion

...

mixin

...

and

...

its

...

CompleteInterface

...

for

...

this

...

task,

...

because

...

it

...

gives

...

you

...

a

...

way

...

of

...

mapping

...

between

...

implementation

...

classes

...

and

...

interfaces

...

for

...

free.

...

This,

...

however,

...

is

...

not

...

recommended,

...

for

...

the

...

following

...

reasons:

...

  • dedicated

...

  • IOC

...

  • libraries

...

  • exist,

...

  • and

...

  • they

...

  • are

...

  • much

...

  • more

...

  • appropriate

...

  • for

...

  • decoupling

...

  • interfaces

...

  • and

...

  • implementations

...

  • you

...

  • can't

...

  • decouple

...

  • in

...

  • such

...

  • a

...

  • fashion

...

  • that

...

  • it

...

  • actually

...

  • makes

...

  • sense

...

  • you

...

  • would

...

  • have

...

  • to

...

  • modify

...

  • the

...

  • interface's

...

  • source

...

  • code

...

  • with

...

  • the

...

  • CompleteInterface

...

  • attribute

...

  • every

...

  • time

...

  • you

...

  • change

...

  • the

...

  • mapping

...

In

...

other

...

words:

...

use

...

something

...

like

...

the

...

castle

...

project's

...

for

...

inversion

...

of

...

control

...

Windsor

...

Container

...

,

...

not

...

the

...

re-motion

...

mixin

...

library.

...

Sample

...

code

...

Find

...

the

...

sample

...

code

...

for

...

this

...

exercise

...

in

...

subversion

...

.

...