A: Dynamic and DynamicProxy

Scott Waldron Updated by Scott Waldron

Dynamic Properties and the DynamicProxy Class

Dino Scripts™ are ideal for reporting. However, just returning a set of built-in objects is rarely enough to generate a report that will make sense to the end user. Database objects are by nature "normalized". Running a sales report with only Sale objects may show things like who the customer is, when the order was placed, etc., but will lack all the information about what items were purchased. In a normalized data structure, the items in a sale are stored in a separate table (thus in a separate object).

The .NET framework can be used for dynamic programming. While the .NET framework is a statically typed system, there are "syntactic sugar" allowances that give a very convincing impression of a dynamic, loosely typed system like Dino. For example, the following code will build (and run!) in C#:

namespace MyTests
{
public class MyClass
{
public MyClass()
{
dynamic d = new Trestle.DynamicProxy();
d.Name = "Jane Witherspoon";
d.Age = 34;
d.ThisIsCool = true;
}
}
}

The DynamicProxy class (in the Trestle® assembly and namespace) is an implementation of the .NET dynamic meta object system. In the code above, by declaring the variable as dynamic, the C# parser and validator know that they should not try to check for the existence of properties at compile time.

How Dino Script™ uses DynamicProxy

The Dino language has a dynamic() function. The language has a provision for making this function pluggable, that is systems that integrate the Dino language can provide their own dynamic object, provided it meets the interface requirements for a dynamic class in the .NET framework. In the ExpressionEvaluator class in Dino.Core, there is this code to enable this behavior:

/// <summary>
/// Set this to return a certain type of dynamic.
/// </summary>
public Func<IDynamicMetaObjectProvider> DynamicFactory
{
get;
set;
}

/// <summary>
/// Do NOT return ExpandoObject for this! It will break
/// public indexing. By default this method creates a
/// <see cref="Dynamitey.DynamicObjects.Dictionary"/>.
/// </summary>
/// <returns></returns>
public virtual IDynamicMetaObjectProvider CreateDynamicInstance()
{
return DynamicFactory?.Invoke() ??
new Dynamitey.DynamicObjects.Dictionary();
}

As you can see from the return value, the default implementation of this is 1) first check to see if the DynamicFactory property returns anything, and if not then 2) return a dynamic object which is defined in one of the dependencies that Dino already uses. By doing this, we prevent Dino from needing to take another dependency simply to return a dynamic object implementation.

When Dino is used with Trestle, we inject the creation function into ExpressionEvaluator like this:

//...
ExpressionEvaluator.Current.DynamicFactory = () => new DynamicProxy();
//...

How did we do?

A: Commands

A: Advanced Command Arguments

Contact