UsageBuilder

jbtule edited this page May 25, 2013 · 1 revision

Introduction

If you are familiar with the Clay Project they have a ClayFactory that uses a really cool inline syntax to initialize a prototype clay object.

      dynamic New = new ClayFactory();

      var person = New.Person(
          FirstName: "George",
          LastName: "Washington"
      );

But a clay object uses a lot of Inversion of Control— you can change it's behavior entirely by plugging in different behaviors,but this flexibility comes with a cost that you may not need to be paying for just a plain old prototype object.

Typical Builder

if you included Dynamitey you can do the same thing

      dynamic New = Builder.New();

      var person = New.Person(
          FirstName: "George",
          LastName: "Washington"
      );

And this runs about 100x faster at accessing properties than the clay object and supports 99% of what a ClayFactory creates.

But there's more flexibility then just that. The DynamicObjects.Builder can actually initialize any object including ExpandoObject

      dynamic New = Builder.New<ExpandoObject>();

      var person = New.Person(
          FirstName: "George",
          LastName: "Washington"
      );

.NET 4.0's built in ExpandoObject runs about 5x faster than DynamicObjects.Builder's default (DynamicObjects.Dictionary) obviously it won't do everything the clay factory's prototype did but since ExpandoObject runs 500x faster than the clay result you probably want to make sure you really needed the extra functionality.

Since DynamicObjects.Builder can work with any object it even can produce the same result as the ClayFactory.

 var New = Builder.New<Clay>()
                  .ObjectSetup(
                   Return<object[]>.Arguments(
                  () => new object[]{
                    new InterfaceProxyBehavior(),
                    new PropBehavior(),   
                    new ArrayPropAssignmentBehavior(),
                    new NilResultBehavior()}))
                  .ArraySetup(
                  Return<object[]>.Arguments(
                  ()=>new object[]{
                    new InterfaceProxyBehavior(),
                    new PropBehavior(),
                    new ArrayPropAssignmentBehavior(),
                    new ArrayBehavior(),
                    new NilResultBehavior()}));

  var directory = New.Array(
                        New.Person().Name("Louis").Aliases(new[] { "Lou" }),
                        New.Person().Name("Bertrand").Aliases("bleroy", "boudin")
                        ).Name("Orchard folks");

Not pretty but you can encapsulate the creation of the New variable and it makes it easy to switch between what prototype object you need.

Simplified DynamicObjects.Builder

The above Builder.New<Type> syntax to create the builder has a lot of flexibility but you have to create it first before you can use the constructing method. If you want a quicker simplified inline syntax and don't need configuration than you can use Build<Type>.NewObject instead.

Advanced DynamicObjects.Builder

The builder can actually setup multiple kinds of builders based on name.


      dynamic New = Builder.New().Setup(
                                    Expando: new Activate<ExpandoObject>(),
                                    Clay: new Activate<Clay>( () => new object[]{
                                                     new InterfaceProxyBehavior(),
                                                     new PropBehavior(),   
                                                     new ArrayPropAssignmentBehavior(),
                                                     new NilResultBehavior()});

     var expandoPerson = New.Expando(
          FirstName: "George",
          LastName: "Washington"
      );       

      var clayPerson = New.Clay(
          FirstName: "George",
          LastName: "Washington"
      );

      //Unsetup names uses the 'Object' builder which if not set is an `DynamicObjects.Dictinoary`
      var defaultPerson = New.Unknown(
          FirstName: "George",
          LastName: "Washington"
      );

Inline Lambda

If you need to inline a lamba you can always do new Func<T>(lambda) or new Action<T>(lambda). Dynamitey has an alternative form that can be used interchangeably.


var regularSyntax = new Func<int,string>(i=>"index: "+i);

var dynamiteySyntax = Return<string>.Arguments<int>(i=>"index: "+i);

var regularSyntax = new Action<string>(hello=>Console.WriteLine(hello));

var dynamiteySyntax = ReturnVoid.Arguments<string>(hello=>Console.WriteLine(hello));

Either work and can be a property on a builder.

     var person = New.Test(
          One: 1,
          Two: 2
          OnePlus: Return<int>.Arguments<int>(x=>x+1)
      );

     var result = person.OnePlus(2);