Getting Started

FluentReflection is pretty easy to understand, there are only a few basic concepts.

Instance & Static

As we all know, there are two types of members: object level, instance members and class level static members. The determination of which type you require are is all in the extension method calls. Calls on a type result in static calls, while calls on an object indicate you want to perform an instance operation.

Static Call

string result = typeof(string).Method("Concat").WithParam(1).Invoke<string>();

Instance Call

int result = "example".Property("Length").GetValue<int>();

Public, NonPublic and other BindingFlags

By default, FluentReflection looks for members with your specified name that are both public and private. However, there may be times when you want to specify a particular visibility or another binding flag. To do this we use the That specification in conjunction with the Is specification.

For example, to require a member to be non-public, use:

var instance = new MyClass();
int result = instance.Field("_count").That(Is.Private).GetValue<int>();

For less common BindingFlags, the Is.Flagged method can be used like so:

var instance = new MyClass();
int result = instance.Field("_count").That(Is.Flagged(BindingFlags.ExactBinding)).GetValue<int>();

These modifiers can be chained using the And method. For example:

var instance = new MyClass();
int result = instance.Property("Name").That(Is.Public.And(Is.Flagged(BindingFlags.DeclaredOnly))).GetValue<string>();

Parameters

Often constructors and methods take parameters and FluentReflection handles these with the WithParams (or WithParam) specifications. The WithParam method naturally takes only one parameter and is generically typed to specify the value of the parameter:

typeof(AClass).Method("MyStaticMethod").WithParam("a string").Invoke();

In the example above, there is no evidence of a generic type. This is because the type is implicit in the type being passed and so the generic type can be left out. This may not always be the case. For example, if a constructor takes an interface, the instance passed to the constructor will have a concrete type but the method will be expecting an interface. In this case the generic type is required:

IMyInterface instance = new MyImpl();
typeof(AClass).Constructor().WithParam<IMyInterface>(instance).Construct<AClass>();

Operations

Obviously the point of reflection is to, in the end, perform some kind of operation on the reflected member. Fields and properties can be gotten and set, methods can be invoked and constructors constructed. These end products are different depending on what type of member you operate on and often result in a return value.

Fields

Operations available for fields are:
GetValue<T>()

and

SetValue(object value)
The generic type on the get value method specifies the return type of the get operation.

Properties

Properties share the GetValue and SetValue methods with fields but also include:
GetValue<T>(params object[])

and

SetValue(object, params object[])
to allow for indexed properties. NOTE: The plan is to change this to use WithParams like methods and constructors in short order.

Methods

Support
Invoke<T>()
and

Invoke()
to support methods that return values and those that return void.

Constructors

Since constructors always return a value, there is a single operation method for constructors:
Construct<T>()
NOTE: Support for static constructors is not currently available as static constructors are effectively called the minute you use the type.

Member Existence

Sometimes it is useful to check whether a member exist (or at least exists with the name, parameters and binding flags you specified) and so FluentReflection provides an Exists property on each of its member specifications. Simply call the property instead of invoking and operation like so:

typeof(string).Method("Noway").That(Is.Public).WithParams(1, false).Exists

Last edited Sep 6, 2011 at 9:48 PM by apjanes, version 15

Comments

No comments yet.