Skip to content

Down Casting Composites

Sagi edited this page Apr 8, 2015 · 20 revisions

When NCop crafts the proxy object it builds it with a specific constructor which accepts all mixin types.

[TransientComposite]
[Mixins(typeof(CSharpDeveloperMixin), typeof(GuitarPlayerMixin))]
public interface IPerson : IDeveloper, IMusician
{
}

/// Proxy
public class PersonImpl : IPerson
{
    private readonly IMusician musician = null;
    private readonly IDeveloper developer = null;

    public PersonImpl(IDeveloper developer, IMusician musician)
    {
        this.musician = musician;
        this.developer = developer;
    }
}

NCop will register a new entry in the [IoC container] for the interface and the implementation (Proxy)
IPerson -> PersonImpl,
But also for each mixin and implementation
IDeveloper -> CSharpDeveloperMixin and IMusician -> GuitarPlayerMixin
. In order to register different implementations for the same interface you need to order NCop to register a named entry. Lets say that we want to create two different composites for IDeveloper.

[TransientComposite]
[Mixins(typeof(JavaScriptDeveloperMixin))]
public interface IJavaScriptDeveloper : IDeveloper
{
}

[TransientComposite]
[Mixins(typeof(CSharpDeveloperMixin))]
public interface ICSharpDeveloper : IDeveloper
{
}

public class JavaScriptDeveloperMixin : IDeveloper
{
    public void Code() {
        Console.WriteLine("JavaScript coding");
    }
}

public class CSharpDeveloperMixin : IDeveloper
{
    public void Code() {
        Console.WriteLine("C# coding");
    }
}

Now you need to order NCop to down cast ICSharpDeveloper and IJavaScriptDeveloper to IDeveloper by applying the As parameter to the TransientCompositeAttributeattribute.

[Mixins(typeof(JavaScriptDeveloperMixin))]
[TransientComposite(As = typeof(IDeveloper))]
public interface IJavaScriptDeveloper : IDeveloper
{
}

[Mixins(typeof(CSharpDeveloperMixin))]
[TransientComposite(As = typeof(IDeveloper))]
public interface ICSharpDeveloper : IDeveloper
{
}

The last thing that you need to do is name each of the composites.

[Named("JavaScript")]
[Mixins(typeof(JavaScriptDeveloperMixin))]
[TransientComposite(As = typeof(IDeveloper))]
public interface IJavaScriptDeveloper : IDeveloper
{
}

[Named("C#")]
[Mixins(typeof(CSharpDeveloperMixin))]
[TransientComposite(As = typeof(IDeveloper))]
public interface ICSharpDeveloper : IDeveloper
{
}

Now we can resolve both types using the ResolveNamed function of the IoC

class Program
{
    static void Main(string[] args) {
        IDeveloper developer = null;
        var container = new CompositeContainer();

        container.Configure();
        developer = container.ResolveNamed<IDeveloper>("C#");
        developer.Code();
        developer = container.ResolveNamed<IDeveloper>("JavaScript");
        developer.Code();
    }
}