-
Notifications
You must be signed in to change notification settings - Fork 44
UsageBuilder
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.
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.
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.
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"
);
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);