Project Description

A fluent API for dynamically creating an anonymous type implementing a specific interface.

Supported Platforms

.NET 4.0 and higher. Silverlight can be added if someone wants it.

Unfortunately, Windows Store and Windows Phone platforms are not currently supported.

Quick Start

Download via NuGet: Nito.AnonymousInterfaces.

The namespace:

using AnonymousInterfaces;

Start with:

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    ... // cool stuff goes here
    .Create();

Then stick in the "cool stuff" you need (examples are below; let the XML documentation guide you).

The Create method will create a new type and then create and return an instance of that type.

You can pass an IMyInterface object in to the Implement method, and any methods you don't override with your "cool stuff" will get forwarded to that object.

If you don't supply an implementation for an interface member, it will be implemented as throwing NotImplementedException. So if you just do Anonymous.Implement<IMyInterface>().Create(), you'll get an implementation that throws NotImplementedException for everything.

Property getters and setters

interface IMyInterface
{
    int Value { get; set; }
}

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .PropertyGet(x => x.Value, () => { return ...; })
    .PropertySet(x => x.Value, value => { ... })
    .Create();

This works as long as there is a property getter.

Methods

interface IMyInterface
{
    void Test();
}

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .Method<Action>(x => x.Test, () => { ... })
    .Create();

This works for most methods, including params methods and parameters with default values; if you need to return a value, just use Func instead of Action. For complex scenarios, see below.

Index getters and setters

interface IMyInterface
{
    string this[int index] { get; set; }
}

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .IndexGet<Func<int, string>>(index => { return ...; })
    .IndexSet<Action<int, string>>((index, value) => { ... })
    .Create();

Events

interface IMyInterface
{
    event Action OnWhatever;
}

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .EventSubscribe<Action>("OnWhatever", value => { ... })
    .EventUnsubscribe<Action>("OnWhatever", value => { ... })
    .Create();

Set-only properties (no getters)

interface IMyInterface
{
    int Value { set; }
}

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .PropertySet<int>("Value", value => { ... })
    .Create();

Methods with "out" or "ref" parameters

interface IMyInterface
{
    void Test(out int arg);
}

// Have to define your own matching delegate type
private delegate void TestDelegate(out int arg);

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .Method<TestDelegate>(x => x.Test, (out int arg) => { arg = ... })
    .Create();

Methods hidden in base interfaces

interface IMyBaseInterface
{
    void Test();
}

interface IMyInterface : IMyBaseInterface
{
    new void Test();
}

IMyInterface instance = Anonymous.Implement<IMyInterface>()
    .Method<Action>(x => ((IMyBaseInterface)x).Test, () => { ... })
    .Create();

Generic methods

Generic methods require an implementation of the interface, because there's no way to construct an open generic delegate type:

interface IMyInterface
{
    void Test<T>();
    // other members
}

private sealed class MyImplementation : IMyInterface
{
    void Test<T>() { ... }
    // usually just throws NotImplementedException for other members
}

IMyInterface implementation = new MyImplementation();
IMyInterface instance = Anonymous.Implement<IMyInterface>(implementation)
    ... // other interface members overridden here
    .Create();

Last edited Nov 17, 2012 at 5:01 AM by StephenCleary, version 7