/// Monday, November 14

Reflex Reflection Library

Introduction

Reflex, short for reflection expressions, is a library in the works to simplify the use of the .NET reflection library. Simply put a consutrctor, method and property class in a string and let Reflex do the work:

// instantiate Math using default constructor, then invoke Add(1,2)
string expression = "Math()::Add(1,2)";
int result = (int) Reflex.Eval(expression);

Without Reflex you would have to get the type, find the constructor, invoke the constructor, cast the the returned type, get the method, build the parameters, then invoke it. What if you already have an instance?

Math m = new Math();
rx = new Reflex(m);
expression = "Add(1,2)";
int result = (int) rx.Invoke(expression);

Expressions

[../../some.dll] SomeClass()::Method()

Loads some.dll, instantiate SomeClass using default constructor, invoke Method()

SomeClass::Method()

Invoke static method Method()

Languages["Boo"].Url

Get the "Boo" entry from dictionary Languages, then get the Urlproperty from the object.

Languages.Boo.Url

Same as above, dictionary entries are treated as properties.

Languages[0].Url

Get the first entry from dictionary Languages, then get the Urlproperty

Require Attribute

In some scenarios, Reflex should be prohibited from blindly invoking methods. For example, mapping a URL to classes and methods is a huge security hole. Create an attribute to mark the methods you wish to expose, then use the overloaded Eval() or Invoke():

// throws an exception, Fibonacci is not marked with [Expose]
Reflex.Eval("Math::Fibonacci(3)", typeof(Expose));
class Math {
 [Expose]
 public int Add(int a, int b) {
  return a + b;
 }

 public int Fibonacci(int n) {
 ...
 }
}

Usage

Map a data row to a class.

string template = @"
My.Person()::
    Name = ""{0}""
    Age = {1}
    Height = {2}
";
expression = string.Format(template, row.Name, row.Age, row.Height);
Person p = (Person) Reflex.Eval(expression);

Map url to execute method.

string queryString = "Math/Add?a=1&b=2";
expression = ToExpression(queryString); // convert to "Math()::Add(1, 2)"
int result = (int) rx.Eval(expression);

Instantiate an object from Web.Config setting.

// retrieve from config
string value = "MGutz.Person, Person";
expression = ToExpression(value); // convert to "[MGutz.Person] Person()"
IPerson person = (IPerson) Reflex.Eval(expression);

Comments:

Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?