Versions Compared

Key

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

...

Let's

...

say

...

we

...

want

...

to

...

build

...

our

...

own

...

configuration

...

from

...

scratch

...

for

...

mixing

...

a

...

floor

...

wax

...

to

...

a

...

dessert

...

topping,

...

as

...

demonstrated

...

in

...

the

...

first

...

exercise

...

of

...

this

...

tutorial

...

– re-motion

...

mixins

...

basics

...

--

...

the

...

'Uses'

...

attribute

...

and

...

the

...

'ObjectFactory'

...

.

...

To

...

this

...

end,

...

we

...

create

...

an

...

empty

...

mixin

...

configuration

...

builder

...

with

...

}
Code Block
MixinConfiguration.BuildNew ()
{code}

{{MixinConfiguration}} is our gateway to the 

MixinConfiguration is our gateway to the re-motion

...

mixin

...

library;

...

BuildNew

...

is

...

a

...

static

...

method

...

that

...

gives

...

you

...

an

...

emtpy

...

builder

...

object.

...

This

...

is

...

not

...

the

...

mixin

...

configuration,

...

it

...

is

...

an

...

intermediate

...

represenation

...

for

...

convenient

...

building.

...

After

...

getting

...

our

...

empty

...

mixin

...

configuration

...

builder

...

,

...

we

...

can

...

add

...

items

...

to

...

it

...

by

...

gluing

...

commands

...

together

...

like

...

this:

...

Code Block
MixinConfiguration.BuildNew () // set up new builder
.ForClass<TargetClass1> ().AddMixin<MixinClass1> ().AddMixin<MixinClass2> ().AddMixinClass<MixinClass3> ()         // mix mixin 1, 2 and 3 to target class 1
.ForClass<TargetClass2> ().AddMixin<MixinClass4> ().AddMixin<MixinClass5> ()                                       // mix mixin 4 and 5 to target class 2
...
.BuildConfiguration (); // make actual configuration from builder
{code}

This

...

manner

...

of

...

piling

...

stuff

...

on

...

an

...

instance

...

is

...

a

...

well-established

...

pattern

...

called

...

the

...

fluent

...

interface

...

pattern

...

.

...

Note

...

the

...

last

...

command

...

in

...

the

...

chain,

...

the

...

concluding

...

.BuildConfiguration

...

.

...

This

...

method

...

creates

...

the

...

actual

...

mixin

...

configuration

...

from

...

the

...

builder

...

representation.

...

The

...

builder

...

is

...

required

...

to

...

make

...

the

...

convenient

...

mechanics

...

of

...

the

...

fluent

...

interface

...

pattern

...

work.

...

For

...

our

...

dessert

...

wax

...

example,

...

this

...

means:

...

}
Code Block
var myMixinConfiguration = MixinConfiguration.BuildNew () // make builder
.ForClass<DessertTopping> ().AddMixin<FloorWax> ()        // add items to the builder by chaining methods (= fluent interface)
.BuildConfiguration ();                                   // run builder to make mixin configuration
{code}

Since

...

we

...

build

...

the

...

mixin

...

configuration

...

ourselves,

...

there

...

is

...

no

...

need

...

to

...

attribute

...

any

...

of

...

the

...

involved

...

classes.

...

What

...

we

...

DO

...

have

...

to

...

do

...

is

...

to

...

set

...

the

...

freshly

...

constructed

...

mixin

...

configuration

...

active

...

for

...

the

...

current

...

thread:

...

}
Code Block
MixinConfiguration.SetActiveConfiguration (myMixinConfiguration); // only affects this thread
{code}

From

...

that

...

point

...

on,

...

our

...

nameless

...

mixed

...

class

...

can

...

be

...

exercised

...

as

...

in

...

the

...

examples

...

on

...

previous

...

pages

...

of

...

this

...

tutorial.

...

Here

...

is

...

a

...

complete

...

listing.

...

Code Block
  // Note that we don't use a [Uses] attribute.
  // We don't need any attributes here, because all
  // configuration work is done via the fluent interface
  // (see listing below).
  public class DessertTopping
  {
    public void TasteGood ()
    {
      Console.WriteLine ("Mmmmmm, tastes terrific!");
    }
  }

  public interface IFloorWaxMixin
  {
    void SealFloor ();
  }

  // Note that we don't use an [Extends] attribute.
  // The method chaining (fluent interface, see below)
  // does all the configuration work.
  public class FloorWaxMixin : IFloorWaxMixin
  {
    public void SealFloor ()
    {
      Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
    }
  }


  class Program
  {
    static void Main (string[] args)
    {
      // 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));

      // instantiate and build a new mixin configuration.
      // In the previous samples, we've done that by using
      // attributes.
      var myMixinConfiguration = MixinConfiguration.BuildNew ()
          .ForClass<DessertTopping> ().AddMixin<FloorWaxMixin> ()   // mix 'FloorWaxMixin' to 'DessertTopping'
          .BuildConfiguration ();

      // make that mixin configuration active for this thread
      MixinConfiguration.SetActiveConfiguration (myMixinConfiguration);

      // this is same old same old... instantiate mixed class
      var myDessertWax = ObjectFactory.Create<DessertTopping> (ParamList.Empty);
      myDessertWax.TasteGood ();
      ((IFloorWaxMixin) myDessertWax).SealFloor ();

      Console.ReadLine ();
    }
  }
{code}  

h5. Sample code

You find the sample code for this exercise [in subversion|https://svn.re-motion.org/svn/Remotion-Contrib/Samples/Mixin/WikiSamples/trunk/WikiSamples.DessertWaxFluentInterface/Program.cs].


Sample code

You find the sample code for this exercise in subversion.