Category: DynamicProxy

Point point one release for Windsor and Castle.Core

Exactly one month after release 2.5.0 we released first minor update to this release for Windsor and Castle.Core. It contains some minor improvements and fixes for issues that were identified after the 2.5 release. Complete changelog for Windsor contains 20 items, and 9 for Castle.Core, including single breaking change, which is deletion of web logger so that Castle.Core has no dependency on System.Web and we no longer need to provide two versions for .NET 4 (one with Client profile support, and one with full profile).

There’s one relatively major feature in the release that you should be aware of – debugger views in Windsor were extended with detection of potential lifestyle mismatches. When you step over your configured container in the debugger the following item may now appear in the list:

mismatches

This lets you detect situations where you have a singleton component that depends on a transient or per-web-request component, which is usually a bug (although there are rare cases when singleton depending on transient is a valid solution).

In addition to the list, the Description will give you… well – description of the situation:

mismatches_text

Notice that this is only a helper and due to dynamic nature of Windsor it can only detect a statically known subset of possible dependencies. As such you should not assume that if the feature does not detect any issues there aren’t any.

You can download the projects from Sourceforge as usual:

Castle Windsor 2.5… the final countdown – beta 1 released (and Core, DynamicProxy, Dictionary Adapter)

Well it’s about time. Due to certain events (like me relocating to the other part of the world) it’s later than planned but it’s here – beta 1 of Castle Windsor 2.5 is available for download.

There’s been quite a lot of changes in the release. Not just in the code but in the entire Castle Project.

We migrated from Subversion to Git, and you can now access the repositories on github. Hopefully this will make things easier for anyone who wants to contribute features and patches to get going, and will raise the level of community contributions to the project (actually it already has, although not as much as I’d like).

We moved from out previous documentation to the new open wiki engine. The documentation is still being migrated and updated but I can say that for Windsor the documentation is already pretty complete and it covers all the new features in version 2.5. The wiki is open for anyone to register and contribute, either by proofreading and fixing spelling errors, expanding existing topics or adding new ones.

Also it’s worth mentioning the awesome work that Andy Pike’s been doing on CastleCasts. The website (built on Castle stack obviously) contains free short screencasts that will help you learn different aspects of the Castle stack. While most of the screncasts are dedicated to Monorail, Andy recently started covering Windsor as well. And the best part is – CastleCasts is an open place for Castle-related screencasts so if you want to record one, and share your knowledge with others go ahead.

What’s in it – Core (now incl. DynamicProxy and Dictionary Adapter)

Here are some of the highlights of the release for Castle.Core.dll

  • Castle.DynamicProxy.dll got now merged into Castle.Core.dll (same with Dictionary Adapter) so now you need to reference just single assembly instead of two.
  • Supports .NET 4 (and .NET 4 client profile)
  • DynamicProxy has now new kind of proxies – Class proxy with target. I blogged about limitations of this approach, so use this with caution
  • DynamicProxy will now let you intercept explicitly implemented interface methods on class proxy
  • DynamicProxy will now let you intercept calls to methods on System.Object (ToString, Equals, GetHashCode) – the default ProxyGenerationHook will still opt out of this though
  • Dictionary Adapter performance improvements.  Proxy class are cached so DA no longer traverses assemblies to find type
  • Dictionary Adapter automatic support for NotifyPropertyChanged. EditableObject, IDataErrorInfo, and validation capabilities.  Just extend from the interface(s) and feature is enabled
  • Dictionary Adapter support for custom HashCode/Equals strategy so you can better support persistence in which and Id usually used for equality
  • Ability to coerce one Dictionary Adapter into another and/or copy properties from one to another.
  • Integrated support for Xml/XPath using standard Xml Serialization attributes – this gives you strongly typed config files (for example)

Plus many more minor fixes, features and improvements. You can see the entire list in changelog.

What’s in it – Windsor

The main dish is obviously Windsor, and there are plenty interesting new features and improvements as well.

And heaps of other smaller improvements and general polish.

Breaking changes

This is a point-five release, which means it is highly compatible with previous release and upgrading should be pretty straightforward and quick. There are some changes though, and we tried to document all of them in breakingchanges.txt file included in the release. Read the file to see the list of breaking changes and upgrade path for each of them. If you find any breaking change not described in the file, or some information that is inaccurate of missing let us know, so that we can improve that for the final release.

In addition to that also some API was made obsolete in this release (most notably the old registration API) to discourage users from its usage. It is not going away anytime soon, but it is highly recommended to migrate code using the now-obsolete API to the alternatives.

What’s next

This is beta 1 release. It means that before the final release no new major features will be added and no breaking changes will be introduced (unless necessary to fix a critical bug, which is unlikely). This release contains only .NET version of Windsor. Version for Silverlight is still in works and will be part of beta 2 release. We’re also working on some sample applications to help you get started using Windsor. The samples will be also included in beta 2 release. So far we have a winforms sample almost ready. If you’d like to contribute a web sample feel more than welcome to contribute.

ETA for beta 2 is in two weeks, if no big issues are found, final release will be out around two weeks after.

Get it, play with it, give us your feedback!

The bits are here, to discuss the release go to our google users group.

Transparently releasing components in Windsor

Disclaimer:

This post is about the idea, not about the implementation. The implementation is crippled, not thread safe, will work only in few scenarios and only if used properly. Do not copy and blindly use this code.

The problem

One of unique features of Windsor is that it manages the lifecycle of objects it creates for you. What this means (among other things) is that it will dispose all disposable objects it instantiates. However to do this, it has to keep a reference to these components. Also that means that in order to properly release the components you have to get hold of the container and once you’re done using the components – explicitly release them with the container.

It may be not desirable from your perspective to do it like this. Ideally, you’d rather use your component, call Dispose and then have Windsor release the component. This is not quite possible, since there’s no way by which Windsor can be notified that your component was disposed. Or is there?

The idea

Since Dispose is an interface method and Windsor has quite powerful AOP capabilities, we can take advantage of that and intercept the call to Dispose and transparently release our component. Let’s build a disposable component first:

public interface IController : IDisposable

{

    int DoSomething();

 

    bool Disposed { get; set; }

}

 

public class Controller : IController

{

    // notice it's not virtual!

    public void Dispose()

    {

        // some clean up logic here

        Disposed = true;

    }

 

    public int DoSomething()

    {

        return 42;

    }

 

    public bool Disposed

    {

        get; set;

    }

}

One important thing to notice about this code – Dispose is not implemented virtually. This will make our sample simpler since we won’t have to deal with recursion.

Then we set up the stage:

[TestFixture]

public class TransparentReleasingTest

{

    private WindsorContainer container;

 

    [SetUp]

    public void SetUp()

    {

        container = new WindsorContainer();

        container.Register(Component.For<ReleaseComponentInterceptor>());

        container.Register(Component.For<IController>().ImplementedBy<Controller>()

                               .LifeStyle.Transient

                               .Interceptors<ReleaseComponentInterceptor>());

    }

 

    [TearDown]

    public void CleanUp()

    {

        container.Dispose();

    }

}

We’ll discuss the ReleaseComponentInterceptor, which is the gist of this post, in a minute. Let’s first create a test:

[Test]

public void Dispose_releases_component()

{

    IController item;

    using (var controller = container.Resolve<IController>())

    {

        item = controller;

        controller.DoSomething();

 

        Assert.IsTrue(container.Kernel.ReleasePolicy.HasTrack(controller));

        Assert.IsFalse(controller.Disposed);

    }

 

    Assert.IsFalse(container.Kernel.ReleasePolicy.HasTrack(item));

    Assert.IsTrue(item.Disposed);

}

Notice that in order for the interceptor to intercept the call to Dispose we need to cast component to IDisposable before calling the method (‘using’ will do that for us). Notice important aspect of this test – it is completely container agnostic. It does not need any kind of explicit nor indirect reference to the container to work and to release the component properly. Let’s now see what happens behind the scenes.

Interceptor

The hero of the day, is the following interceptor:

[Transient]

public class ReleaseComponentInterceptor : IInterceptor

{

    private static readonly MethodInfo dispose = typeof(IDisposable).GetMethods().Single();

    private readonly IKernel kernel;

 

    public ReleaseComponentInterceptor(IKernel kernel)

    {

        this.kernel = kernel;

    }

 

    public void Intercept(IInvocation invocation)

    {

        if (invocation.Method == dispose)

        {

            kernel.ReleaseComponent(invocation.Proxy);

        }

        else

        {

            invocation.Proceed();

        }

    }

}

Most of the time it just sits there and does nothing. However if it detects a call to Dispose, it releases the component from the container, which will in turn invoke the Dispose again (this time on the class, not interface, and since the interface is implemented non-virtually that second call won’t be intercepted), perform all other decommission job for the component as well as all its dependencies and it will release it, so that it can be garbage collected afterwards.

This is just another useful trick, worth knowing if you want to keep your design container agnostic while still reaping full benefits it provides.

Castle Windsor 2.1, Dynamic Proxy 2.2 and more released!

Update: Due to a regression error discovered in Windsor Factory Support Facility, we decided to act fast and provide updated package of Windsor, without the issue. Get it here. Sorry for the inconvenience.

Castle Project

What better way of starting a new year can there be, than fresh set of releases from Castle Project?!

Core 1.2 (with more)

Castle Core 1.2 has now its own, separate package. Since the beta few things have changed

  • Email sender component is now integrated with Core, so if you were using it, you now should look for it in Castle.Core.dll. The version shipped with Core 1.2 has the following major breaking changes:
    – Removed Message, MessageAttachment and MessageAttachmentCollection classes and replaced them with MailMessage, Attachment and AttachmentCollection from .NET classes in System.Net.Mail
  • Logging services (integration of Castle’s logging abstraction with log4net and NLog) is now packaged with Core. Notice that these are dependent on Core (just like it used to be). Castle does not have dependency on any of these, so don’t freak out.
  • few minor bugs were fixed, but nothing serious. You should be able to just switch the reference to new version and start using it with no changes to your code.
  • We ship four versions: for .NET 2.0, for .NET 3.5, for Silverlight 3.0 and for Mono 2.6

Get it here.

Dynamic Proxy 2.2

This is a pretty significant release. If you haven’t before, read what we had in beta. Since then, the following has changed

  • Interface members on proxies are behaving almost identical to version 2.1 (change from beta). That means that they take long name of explicit implementation (InterfaceName.Method() instead of Method()), only if you already have a method called Method() on your proxy, either from base class or other interface. And even then, it will still be public, which makes it more transparent to the user.
  • We ship three versions: for .NET 2.0 (this is the last version to support .NET 2.0), .NET 3.5 and Silverlight 3.0

Get it here.

MicroKernel/Windsor 2.1.1 (with support for Silverlight)

Probably the biggest thing about this release is that it includes a Silverlight version. There are a couple more highlights thought

  • revamped typed factory facility
  • added ability to specify Type Forwarding via XML config with the following syntax:
    <component

      id="hasForwards"

      type="Castle.MicroKernel.Tests.ClassComponents.TwoInterfacesImpl, Castle.MicroKernel.Tests"

      service="Castle.MicroKernel.Tests.ClassComponents.ICommon, Castle.MicroKernel.Tests">

      <forwardedTypes>

        <add service="Castle.MicroKernel.Tests.ClassComponents.ICommon2, Castle.MicroKernel.Tests" />

      </forwardedTypes>

    </component>

  • added DynamicParameters (with additional option to return delegate to be called upon component’s destruction)
  • added OnCreate method, which lets you act upon component after it’s created, and before it’s removed (see this Tehlike’s post. Notice it’s not in a facility now, so it just works out of the box.)
  • added lazy component loader
  • major performance improvements in certain scenarios
  • and many bugfixes, see commit log for full list if you’re interested
  • We ship two versions: for .NET 3.5 and for Silverlight 3.0
  • There is also logging facility included in the package. Again – neither MicroKernel, nor Windsor depend on it, so don’t freak out.

Get it here.

We’re already gathering ideas for the next version, so go ahead to the Castle UserVoice page and tell us, what you’d like to see in the next version!

Learning in the open – Sample application for Castle stack

We’re getting really close to new release of major Castle Project elements (Monorail 2.0, ActiveRecord 2.1, Windsor 2.1…). Coincidently I started building a small application on top of the stack, and I thought it would be a good idea to make this a “learning in the open” experience, and share my progress on this blog.

This will mostly (at least initially) be a rework of Ayende’s old series, but I will update it to the latest version of the projects and try to discuss some new features as we go along.

I don’t have the application ready yet. This is a journey for me, and as I don’t really have much experience with either Monorail or ActiveRecord, I may do stupid things. That’s the part where your feedback comes into play. I want to drive this series on feedback in much greater degree than the series on Dynamic Proxy. If you want me to dive into details on certain topics – let me know. If you think I should have done something differently and revisit some parts – let me know.

That’s all for now – see you next time.

Castle Dynamic Proxy 2.2 beta in the wild!

Jono just pushed the first beta version of the Castle Dynamic Proxy 2.2 to the SourceForge.

Don’t let the minor version number mislead you – this is a substantial improvement over the version 2.1. The changelog contains over 40 positions. I’m going to go over the most important ones here.

  • Official support for Silverlight 2 or newer.
  • Last version to support .NET 2.0.
  • Substantial performance improvements (which includes more aggressive caching). Just see this:
    dp_perf
    If you’re interested the code for this pseudo-benchmark is here.

Notice that this benchmark measures only time it takes to generate certain number of distinct proxy types. It is here to outline strengths of new version, and does not serve as reliable comparison. You’re unlikely to observe similar speedup in your application. However if you’re creating many proxy types you will notice better performance. The more proxies, the greater improvement.

  • Better support for medium trust scenarios (you will need .NET 2.0 SP2 for this).
  • Significantly broadened range of supported scenarios around generics.
  • Added logging so that you can gain insight into what DP is doing (see Jonathon’s post here).
  • Improved exception messages, so that they are more descriptive and point to a solution.
  • Changed how proxy types are named so that it looks better in logs.
  • Improved handling of mixins, so that it’s now legal to mix in type that implements the same interface as target type, or proxied type.
  • Improved handling of interface proxies with target interface.
  • Added ability to change not only invocation target but also the proxy target in interface proxies with target interfaces
  • … and many more… see the Changes.txt for the full list.

There are few breaking changes that while should not affect vast majority of users, can affect some.

  • All (almost) interface members are now implemented explicitly by the proxy type. This may affect you if you’re reflecting over the proxy types. There is an exception to this rule – for class proxies, when class implements interface member virtually, that member will be implemented implicitly on the proxy type.
  • invocation.MethodInvocationTarget now always points to the method that overrides proxied method on a target type. This means that it’s null when target is null (for interface proxies).
  • many internally used types changed, but you shouldn’t be affected.

 

Last but not least.

This is a beta release. Remember it may contain bugs. However we feel it’s pretty stable at this point. Download it, use it, and if you find any issues, report them so that we can fix them before the final release.

Link is here.

Castle Dynamic Proxy FAQ: why there’s no “class proxy with target”

One of the commonly asked questions about Castle Dynamic Proxy:

How do I use CreateClassProxy to wrap an existing object to intercept calls to its virtual members?

Short answer is – you can’t. And if you think about it, there’s a very good reason for that.

Since classes are stateful, and there’s no requirement that all their members are virtual, you could end up with inconsistent state, where part of the state comes from proxy object, part comes from the target object. This would lead to bizarre behavior and bugs, that would be hard to catch. For that reason Dynamic Proxy does not expose this functionality.
You can either expose the required set of API as interface and create interface proxy with target interface, or to create a wrapper class.

Example

If that’s not clear enough, consider the following example of how such proxy could look like and behave:

class Program

{

    static void Main(string[] args)

    {

        var joe = new PersonImpl(17);

 

        Debug.Assert( joe.IsAdult() == false );

        var proxy = new PersonProxyWithTarget( joe );

        Debug.Assert(proxy.IsAdult() == false);

        proxy.HasBirthday();

        Debug.Assert(joe.IsAdult() != proxy.IsAdult()); // <- we have an issue here

    }

}

 

public abstract class Person

{

    protected int age;

 

    public abstract int HasBirthday();

 

    public bool IsAdult()

    {

        return this.age >= 18;

    }

}

 

public class PersonProxyWithTarget : Person

{

    private readonly Person target;

 

    public PersonProxyWithTarget(Person target)

    {

        this.target = target;

    }

 

    public override int HasBirthday()

    {

        CallInterceptors();

        return target.HasBirthday();

 

    }

 

    private void CallInterceptors()

    {

        //calls interceptors

    }

}

 

public class PersonImpl : Person

{

    public PersonImpl( int age )

    {

        this.age = age;

    }

 

    public override int HasBirthday()

    {

        return this.age++;

    }

}

As you can see here, we have a class which has some state in it. We then create a proxy, and call some methods. The important thing is the last assert. Proxy returns invalid results to us – we have a bug! While the proxy should be transparent, and behave as if it was the joe himself, it returns false values to us. This is not something that can be worked around, hence no class proxies with targets.

InterfaceProxyWithTarget / InterfaceProxyWithTargetInterface – what’s the difference?

There seems to be much confusion around two kinds of proxies that Castle Dynamic Proxy provides – InterfaceProxyWithTarget and InterfaceProxyWithTargetInterface. On the surface they both appear to be doing the same thing.

Rule of thumb:

If you’re not sure which one you want – you want the one with the longer, confusing name – InterfaceProxyWithTargetInterface.

InterfaceProxyWithTargetInterface seems to be used less often, which is a shame, because what people really want 99% of the time is actually InterfaceProxyWithTargetInterface. However I suppose due to it’s extremely confusing name, and no clear apparent distinction between InterfaceProxyWithTargetInterface and InterfaceProxyWithTarget people tend to pick just the one with shorter name.

Also in previous versions of Dynamic Proxy (up to, and including v2.1) InterfaceProxyWithTargetInterface had some bugs, and had less overloads, which made it less convenient to use than the other one. This is (going to be) greatly improved in version 2.2 (and is available in the trunk now), so there’s really no reason not to use InterfaceProxyWithTargetInterface.

Why’s that? There are two advantages InterfaceProxyWithTargetInterface provides:

  • when you use InterfaceProxyWithTargetInterface its invocations will also implement IChangeProxyTarget interface which lets you change the target object that the call will be routed to.
  • secondly, and most importantly – InterfaceProxyWithTargetInterface make much better use of cache.

The second one, is actually the most important difference, and as you most of the time won’t care about changing invocation target, you most certainly want to use caching as much as possible. In case of InterfaceProxyWithTargetInterface type of the target object is not taken into account, whereas for InterfaceProxyWithTarget it is. If that’s not clear enough, let’s see that in code:

var proxy1 = generator.CreateInterfaceProxyWithTargetInterface<IOne>(new One());
var proxy2 = generator.CreateInterfaceProxyWithTargetInterface<IOne>(new OneTwo());
Assert.AreEqual(proxy1.GetType(), proxy2.GetType());
 
var proxy3 = generator.CreateInterfaceProxyWithTarget<IOne>(new One());
var proxy4 = generator.CreateInterfaceProxyWithTarget<IOne>(new OneTwo());
Assert.AreNotEqual(proxy3.GetType(), proxy4.GetType());

Technorati Tags: ,

Castle Dynamic Proxy tutorial part XV: Patterns and Antipatterns

This is part fifteen of my tutorial on Castle Dynamic Proxy.

We’ve covered almost all of Dynamic Proxy. If you followed along through this series, you now know 95% of Dynamic Proxy 2.1 features that get used 99,9% of the time. Now is the time to wrap up, and with that we’ll review some of the most common pitfalls that you may encounter when developing code on top of Dynamic Proxy.

Leaking this

Consider this simple interface/class pair

public interface IFoo
{
	IFoo Bar();
}

public class Foo : IFoo
{
	public IFoo Bar()
	{
		return this;
	}
}

Now, let’s say we create a proxy for IFoo with target and use it like this:

var foo = GetFoo(); // returns proxy
var bar = foo.Bar();
bar.Bar();

Can you see the bug here? The second call is performed not on a proxy but on a target object itself! Our proxy is leaking its target.

This issue obviously does not affect class proxies (since in that case proxy and target are the same object). Why does not Dynamic Proxy handle this scenario on its own? Because there’s no general easy way to handle this. The example I showed is the most trivial one, but proxied object can leak this in a myriad of different ways. It can leak it as a property of returned object, it can leak it as sender argument of raised event, it can assign this to some global variable, it can pass itself to a method on one of its own arguments etc. Dynamic Proxy can’t predict any of these, nor should it.

In some of these cases there is often not much you can do about it, and its good to know that problem like this exist, and understand its consequences. In other cases though, fixing the issue is very simple indeed.

public class LeakingThisInterceptor:IInterceptor
{
	public void Intercept(IInvocation invocation)
	{
		invocation.Proceed();
		if(invocation.ReturnValue == invocation.InvocationTarget)
		{
			invocation.ReturnValue = invocation.Proxy;
		}
	}
}

You add an interceptor (put it as last one in the interceptors pipeline), that switches the leaking target back to proxy instance. It’s as simple as that. Notice that this interceptor is targeted specifically at the scenario from our example above (target leaking via return value). For each case you will need a dedicated interceptor.

Override equality

One of the most common mistakes when it comes to Dynamic Proxy is not overriding Equals/GetHashCode methods on proxy generation hooks and interceptor selectors, which means you’re giving up caching and that in turn coupled with bugs in BCL means performance hit (plus increased memory consumption).

Solution is very simple, and there’s no exceptions to this rule – always override Equals/GetHashCode methods on all your classes implementing either IProxyGenerationHook or IInterceptorSelector.

As of Dynamic Proxy 2.5 IInterceptorSelector implementations need not override Equals/GetHashCode for the caching to work, since changed proxy generation algorithm now only cares whether selector is present or not.

Make your Proxy Generation Hooks purely functional

Pure function, is a function that for given set of inputs always returns the same output. In case of proxy generation hook, it means that two equal (as specified by overriden Equals/GetHashCode methods) proxy generation hooks will for given type to proxy return the same values from their methods, and when asked again about the same type will again return the same values/throw the same exceptions.

This is a major assumption that Dynamic Proxy makes, and that’s what makes the caching mechanism work. If proxy generation hook is equal to the one already used to generate a proxy type, Dynamic Proxy will assume it would return the same values as the other one, which would result in identical proxy type, so it cuts through the generation process and returns the existing proxy type.

Make your supporting classes serializable

If you’re going to be serializing your proxies, you should make all the classes that go with it serializable. That includes proxy generation hooks, interceptors and interceptor selectors. Otherwise you will get an exception when trying to serialize your proxies. It is not mandatory, but I find it useful. Notice that you will need this also when persisting your proxy assembly to disk.

Use ProxyGenerationHooks and InterceptorSelectors for fine grained control

Do your interceptor’s methods look like this?

public void Intercept(IInvocation invocation)
{
	if(invocation.TargetType!=typeof(Foo))
	{
		invocation.Proceed();
		return;
	}
	if(invocation.Method.Name!="Bar")
	{
		invocation.Proceed();
		return;
	}
	if(invocation.Method.GetParameters().Length!=3)
	{
		invocation.Proceed();
		return;
	}
	DoSomeActualWork(invocation);
}

If they do this often means you’re doing something wrong. Move the decisions to proxy generation hook and interceptor selector

  • Do I ever want to intercept this method? If the answer is no, use proxy generation hook to filter it out of methods to proxy.

Notice that due to bug in Dynamic Proxy 2.1, if you choose not to proxy method on interface proxy, you will get an exception. Workaround for this is to say you want to intercept the method, and then use interceptor selector to return no interceptors for the method. This bug is fixed in Dynamic Proxy 2.2

  • If I do want to intercept this method, which interceptors do I want to use? Do I need all of them? Do I need just a single one? Use interceptor selector to control this.

On the other hand, remember that as every feature this one is also a double edged sword. Too liberal use of proxy generation hooks and interceptor selectors may greatly decrease efficiency of proxy type caching, which may hurt your performance. As always think how much control you need and what the implications on caching will be. Sometimes single if on top of your interceptor is lesser evil than increasing number of proxies required tenfold. As always – use the profiler in scenarios that mimic your production scenarios as closely as possible to check which option is the best for you.

SRP applies to interceptors

SRP stands for Single Responsibility Principle, which means that a class should do just one thing. Many people seem to forget about it when it comes to interceptors. They create one monstrous interceptor class that tries to do all the things they need from Dynamic Proxy – logging, security checking, parameter verification, augmenting target objects with behavior and many more.

Remember that Dynamic Proxy lets you have many interceptors per method call. Use this ability to split behavior between interceptors. You may end up with some general purpose interceptors for things like logging that you use for each intercepted method on each class. As long as all it does is logging – that’s ok.

You may end up with some interceptors that are used for methods on just some classes, like classes inheriting from common base class. As long as these interceptors do just one thing – that’s fine.

You may end up with some interceptors that exist solely for the purpose of intercepting just a single method on specific class or interface. That also is fine. Use interceptor selectors to match interceptors to their respective targets, and don’t be afraid to have multiple interceptors per method.

Technorati Tags: ,

Castle Dynamic Proxy tutorial part XIV: Persisting proxies

This is part fourteen of my tutorial on Castle Dynamic Proxy.

Wow, what I had planned as few parts tutorial has turned to nothing less than full examination of Dynamic Proxy capabilities. Of all most important features we’ have basically just one left – proxy persistence, which is what we’re going to talk about today.

Discussion

Although Dynamic Proxy’s name suggests that it’s useful for… well creating proxies on the fly at runtime, there are other scenarios where the framework can be useful. We’ve seen one such scenario last time, when we created mixins, not using proxying at all.

Also the dynamic aspect of proxies is not always what we want. This is not so apparent in server application where application starts once and runs (hopefully) for a long time without restart. In the desktop applications however, we might find ourselves creating lots of identical proxies over and over again each and every time user starts the application.

This may degrade the perception of the application from users perspective, because it will take a lot of time to start. When you have many proxy types, things may get quite bad, due to bug in BCL. I call it a bug but it manifests itself by nonlinearly increasing time that creating of each subsequent proxy type takes (Mono apparently does not have this issue. I created a Connect ticket for it here. Please vote on the issue).

In some scenarios using static weaver like PostSharp will be sufficient. However it is not an option if the shape of your proxies depends on some dynamic aspects of user environment, configuration etc. In this case you may not know which proxies and how shaped until your software is on the users machine.

Let’s say you created a WPF application that allows its GUI to be extended with third party extensions, and that you use Dynamic Proxy to dynamically create ViewModels and INotifyPropertyChange on top of your POCO models. Clearly using static weaver is not an option here, because if would defy the whole point of dynamic extensibility.

However once an extension is installed, it’s really no point in recreating proxies for models in it over and over again. Ideally you would want to create them once, the first time you load the extension, and then reuse them… at least until user installs updated version of the extension.

Good news is, (as you probably suspected anyway) it is possible using Dynamic Proxy. There’s no support for determining whether or not you should reuse existing proxies, but this is very scenario specific so having any code for this in the framework itself wouldn’t make much sense anyway. Let’s look at the code.

Let’s see some code

So far we’ve been creating ProxyGenerator instances using default constructor.

var generator = new ProxyGenerator();

If we want to persist our proxies, we have to write more code:

var savePhysicalAssembly = true;
var strongAssemblyName = ModuleScope.DEFAULT_ASSEMBLY_NAME;
var strongModulePath = ModuleScope.DEFAULT_FILE_NAME;
var weakAssemblyName = "Foo.Bar.Proxies";
var weakModulePath = "Foo.Bar.Proxies.dll";
var scope = new ModuleScope(savePhysicalAssembly, strongAssemblyName, strongModulePath, weakAssemblyName, weakModulePath);
var builder = new DefaultProxyBuilder(scope);
var generator = new ProxyGenerator(builder);

We have to create ModuleScope ourselves (which we’ll later use to save the assembly to disk) passing true, as first argument, to tell DynamicProxy that we want to persist the assembly with generated types. If we didn’t do it, we would get an exception if we tried to save the assembly. We then pass two pairs of assemblyname/filename – strongly named and weakly named version. If you intend to use just one (like in this example I’m going to only save weakly named assembly) you can pass the default values for strongly typed version defined as constants on ModuleScope type.

Save me, Save me

That was the first part of the task. We then use the generator to create the proxy types we need, and when we’re done (most likely upon closing the program) we use scope to save the assembly.

scope.SaveAssembly(false);

The argument value of false means that we want to save the assembly without strong name.

generatedProxyAssembly

And after the call the assembly lands safely in the designated folder under the name provided in the constructor. You can now fire up Reflector and see the inner workings of proxy types if that’s what you want.

reflector

One small catch – remember that you only can call save once on a module scope. If you don’t Dynamic Proxy will remind you:

assemblySaveTwiceError

Let’s get it back

We now have just one element missing, that is loading saved types. As I said finding the assembly itself is your responsibility. When you do, and decide to use it, you do it like this:

Assembly proxyAssembly = GetProxyAssembly();
scope.LoadAssemblyIntoCache(proxyAssembly);

The LoadAssemblyIntoCache method will look for proxy types in the assembly and add all it finds to the cache, so that the next time proxy generator asks for type matching one of cached one, that type will be used, instead of creating a new one.

Two things to note here:

You can load more than one assembly into the module scope’ cache (duplicates will be overriden).

You can save the dynamic assembly even after you’ve loaded types from other assemblies to its scope. Note that only types generated in this new assembly will be saved, not the ones loaded from other assemblies (which is pretty logical).

If you want to check before saving if any new types were generated, you can use the following piece of code:

Type[] types = scope.ObtainDynamicModuleWithWeakName().GetTypes();
if(types.Length>0)
{
    //there are new types.
}

Wrapping up

That would basically be it. We pretty much covered every aspect of the framework, and hopefully by now you have pretty good understanding of what and how you can achieve with it. If you think there’s something missing, or you’d like me to talk more about certain topics I already touched let me know in the comments.

Technorati Tags: ,