How pointless, since this design could be, for some reason, it intrigued me, and I quickly mocked the implementation of Castle DynamicProxy to create objects that combine multiple interfaces.
Mixin factory provides two methods:
object CreateMixin(params object[] objects)
Returns an object that implements any number of interfaces. To go to the implemented interface, you must pass the returned object to this interface.
TMixin CreateMixin<TMixin, T1, T2>(T1 obj1, T2 obj2)
Returns an interface that implements two other interfaces to achieve strong typing. This combining interface must exist at compile time.
Here are the objects:
public interface ICat { void Meow(); int Age { get; set; } } public interface IDog { void Bark(); int Weight { get; set; } } public interface IMouse { void Squeek(); } public interface ICatDog : ICat, IDog { } public interface ICatDogMouse : ICat, IDog, IMouse { } public class Mouse : IMouse { #region IMouse Members public void Squeek() { Console.WriteLine("Squeek squeek"); } #endregion } public class Cat : ICat { #region ICat Members public void Meow() { Console.WriteLine("Meow"); } public int Age { get; set; } #endregion } public class Dog : IDog { #region IDog Members public void Bark() { Console.WriteLine("Woof"); } public int Weight { get; set; } #endregion }
Pay attention to the ICatDog interface. I thought it would be great if the dynamic proxy returns something strongly typed and can be used where any interface is accepted. This interface will need to be determined at compile time if strong typing is really desired. Now for the factory:
using Castle.DynamicProxy; public class MixinFactory {
Usage is best explained in these unit tests. As you can see, the second method returns a secure interface of the type that without any visibility binds any number of interfaces.
[TestMethod] public void CreatedMixinShouldntThrow() { ICat obj1 = new Cat(); IDog obj2 = new Dog(); var actual = MixinFactory.CreateMixin(obj1, obj2); ((IDog)actual).Bark(); var weight = ((IDog)actual).Weight; ((ICat)actual).Meow(); var age = ((ICat)actual).Age; } [TestMethod] public void CreatedGeneric3MixinShouldntThrow() { ICat obj1 = new Cat(); IDog obj2 = new Dog(); IMouse obj3 = new Mouse(); var actual = MixinFactory.CreateMixin<ICatDogMouse>(obj1, obj2, obj3); actual.Bark(); var weight = actual.Weight; actual.Meow(); var age = actual.Age; actual.Squeek(); }
I talked about this in more detail and provided the source and tests. You can find it here .
Igor Zevaka
source share