-
Notifications
You must be signed in to change notification settings - Fork 7
Down Casting Composites
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 PersonProxyImpl : IPerson
{
private readonly IMusician musician = null;
private readonly IDeveloper developer = null;
public PersonProxyImpl (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
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 will 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");
}
}
You'll have to order NCop to do two things:
- Down cast
ICSharpDeveloper
andIJavaScriptDeveloper
toIDeveloper
by applying the As parameter to theTransientCompositeAttribute
attribute.
- Name each of the composites by applying the
NamedAttribute
attribute.
[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();
}
}
The expected output should be:
"C# coding"
"JavaScript coding"
Your end result of the code should be similar to this:
using System;
using NCop.Composite.Framework;
using NCop.Mixins.Framework;
namespace NCop.Samples
{
public interface IDeveloper
{
void Code();
}
public class JavaScriptDeveloperMixin : IDeveloper
{
public void Code() {
Console.WriteLine("JavaScript coding");
}
}
public class CSharpDeveloperMixin : IDeveloper
{
public void Code() {
Console.WriteLine("C# coding");
}
}
[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
{
}
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();
}
}
}