Castle Dynamic Proxy tutorial part XIII: Mix in this, mix in that

This is 13th part of Castle Dynamic Proxy tutorial. You can find all previous parts here.

So far we covered most of basic features of Dynamic Proxy, except for one – mixins. Not getting into theoretical details, mixin is an object that stitches many other objects together, exhibiting behaviors of all these objects. Let me illustrate that in pseudo code:

var dog = Dog.New();
var cat = Cat.New();
var mixin = mixin(cat, dog);
mixin.Bark();
mixin.Meow();

In most languages this is achieved through multiple inheritance, but this is not allowed in the CLR, which imposes certain limitations on how mixins are implemented and work in Dynamic Proxy. We can’t have multiple base classes, but we can implement multiple interfaces and this is what Dynamic Proxy uses for mixins. Let’s see an example of how you would use them:

var options = new ProxyGenerationOptions();
options.AddMixinInstance(new Dictionary<string, object>());
return (Person)generator.CreateClassProxy(typeof(Person), interfaces, options);

We’re mixing class Person with Dictionary (which could be useful if you want to attach generic information store to a person). We need ProxyGenerationOptions for that. We add mixin to options using AddMixinInstance method, passing the dictionary we want to use. Next we create class proxy for Person class using the options with mixin. The Person class can by just an any ordinary, non-sealed class.

public class Person
{
    public string Name { get; set; }
     public int Age { get; set; }
}

Notice that none of its properties is virtual nor it implements any interface. That’s ok, because we don’t want to intercept any calls to Person (although we still could, obviously).

Let’s now look at the list of interfaces the proxy implements:

System.Collections.Generic.ICollection`1[System.Collections.Generic.KeyValuePair`2[System.String,System.Object]]
System.Collections.Generic.IEnumerable`1[System.Collections.Generic.KeyValuePair`2[System.String,System.Object]]
System.Collections.IEnumerable
System.Collections.Generic.IDictionary`2[System.String,System.Object]
System.Collections.ICollection
System.Collections.IDictionary
System.Runtime.Serialization.IDeserializationCallback
System.Runtime.Serialization.ISerializable
Castle.Core.Interceptor.IProxyTargetAccessor

We have the standard IProxyTargetAccessor, and all the interfaces implemented by generic Dictionary. We can pass around our proxy as Person, but at any time cast it to any of the interfaces and use them.

static void Main(string[] args)
{
    var person = CreateProxy();
    var dictionary = person as IDictionary;
    dictionary.Add("Next Leave", DateTime.Now.AddMonths(4));
    UseSomewhereElse(person);
}

private static void UseSomewhereElse(Person person)
{
    var dictionary = person as IDictionary<string,object>;
    var date = ((DateTime) dictionary["Next Leave"]).Date;
    Console.WriteLine("Next leave date of {0} is {1}", person.Name, date);
}

Notice that you’re casting the proxy to an interface. If you tried to cast to Dictionary<,> class, you’d get an exception. Out proxy class inherits from Person, not Dictionary<,> – that’s the limitation I talked about. What we have here is a class proxy, mixed with interface proxy with target, in one object. We obviously can mix in more than one object, but there are other limitations.

You don’t specify which mixin interfaces you want to forward to which mixin. This is implicit – if mixin implements an interface, it will be forwarded to that mixin instance, unless someone else implements it as well. You can’t have two mixins that implement the same interface. You can’t have mixin implement same interface as target, nor can you have a mixin implementing one of additional interfaces to proxy. In any of these cases when trying to create a proxy you will get an error.

This is not a very serious issue though, and I think in most cases it should be enough. In case you need more power, Dynamic Proxy v2.2 will have better support for mixin, allowing scenarios that are not possible in current version.

Technorati Tags: ,

Posted 08-12-2009 10:00 AM by Krzysztof Koźmic

[Advertisement]

Comments

DotNetShoutout wrote Castle Dynamic Proxy tutorial part XIII: Mix in this, mix in that - Krzysztof Kozmic - Devlicio.us
on 08-12-2009 6:25 PM

Thank you for submitting this cool story - Trackback from DotNetShoutout

on 08-13-2009 12:57 PM

Pluralsight On-Demand! I plan to have a full post on Pluralsight On- Demand! very soon. I became a subscriber recently and have found it to be an amazing training tool. Its just ike being in the classroom with the best instructors in the business and

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)