Category: Castle

Castle Dynamic Proxy tutorial part VII: Kinds of proxy objects

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

So far all we have been doing with our simple freezable library is creating a proxies for classes. Not only that, we also introduced one artificial limitation – proxied classes had to have default, parameterless constructor. You can see it by writing the following test:

[Fact]
public void Freezable_should_be_able_to_call_nonDefault_constructor()
{
    var dog = Freezable.MakeFreezable<Dog>("Rex");
    Assert.Equal("Rex", dog.Name);
}
 
public class Dog
{
    public Dog(string name)
    {
        Name = name;
    }
 
    public virtual string Name { get; set; }
}

This test however will not compile.

dptutorial_7_no_default_constructor_error

If we tried to proxy a class with no such constructor, we would get a compilation error.

The compile time error would be a result of the new() generic type constraint we put in MakeFreezable method. It is important to understand that it has nothing to do with Castle Dynamic Proxy. If we removed the constraint we would be able to compile the code, and then get the exception from Dynamic Proxy at runtime: “System.MissingMethodException : Constructor on type ‘DogProxyc319d54e871741668ed468410d1b1013’ not found”.

There is however an overload of CreateClassProxy method that allows you to pass parameters to proxied type constructor. All we need to do, is to refactor the MakeFreezable method.

public static TFreezable MakeFreezable<TFreezable>(params object[] ctorArguments) where TFreezable : class
{
    var freezableInterceptor = new FreezableInterceptor();
    var options = new ProxyGenerationOptions(new FreezableProxyGenerationHook()) { Selector = _selector };
    var proxy = _generator.CreateClassProxy(typeof(TFreezable), new Type[0], options, ctorArguments,
                                            new CallLoggingInterceptor(), freezableInterceptor);
    return proxy as TFreezable;
}

We remove the new() constraint, since it obviously is not needed. We also add an array parameter to the method that we can use to pass arguments to the proxied type constructor. We can use params C# keyword to make the calling of the method a little bit more convenient.

Note that, since we’re passing the arguments as untyped array of objects, you can still get a runtime error if you pass incorrect arguments. This solution is also not refactoring friendly, so If you refactor your constructor and for example reorder its parameters, the parameters passed to MakeFreezable will not be reordered. You might want to change this by using lambda expressions as I described here a while ago. With that you get refactoring support and strong typing.

Other than class proxies, Proxy generator class is able to create three different kinds of interface proxies:

dptutorial_7_proxy_kinds

  • Proxy with target. This one is very easy to explain. We want to proxy an interface. Since interface can’t exist on its own, we need a class that implements it. The instance of this class is the target. It’s very similar to the class proxy we’ve been talking about.
  • Proxy without target. This one is tricky. You don’t supply target implementation for the interface. Dynamic Proxy generates it for you at runtime, using interceptors to provide behavior for its methods.
  • Proxy with target interface. This one is quite similar to proxy with target. You do have to provide a target implementation for the interface. The difference is, you can swap it later, and make the method be called on some other object.

We will cover each kind of interface proxy in forthcoming parts of the tutorial, so that hopefully this will all become crystal clear.

If you have any suggestions or questions, feel free to leave a comment.

Technorati Tags: ,

Castle Dynamic Proxy tutorial part VI: handling non-virtual methods

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

We talked about how Dynamic Proxy proxying mechanism works, but so far we only briefly spoke about its limitations. The main limitation is the fact, that it can not intercept non-virtual calls. This may be an issue of varying importance.

In case of libraries such as NHibernate, which uses DynamicProxy for lazy loading, when your member is not virtual, you can’t lazy load it. This may be a drawback for performance, but your program should be able to work nonetheless.
On the other hand, for libraries like Rhino.Mocks, or MoQ, that use DynamicProxy for creating mocks and stubs, not being able to intercept a call, means you can’t mock its behavior and the response. This is a critical issue.
Similarly in case of our sample Freezable library, if a setter is not virtual, we can’t intercept calls to it, and that means we can not warrant that the state of the object will not change.

When we talked about ProxyGenerationHook, I mentioned that it has a NonVirtualMemberNotification method, that gets called when proxy generator encounters method it can not proxy.
In case of freezable library, we took simplistic assumption that state of the object can only change via property setters. In this case if just any method we encounter is non-virtual we don’t care. Since we assume that it can’t change the state of our object anyway, we may as well let it be non-virtual and still deliver on our promise.
However, if we encounter a non-virtual property setter, we should throw an exception to indicate that we deny taking any responsibility for this objects immutability.

Enough theory – let’s write some tests to get a cleaner picture of what we want to achieve.

[Fact] 
public void Freezable_should_freeze_classes_with_nonVirtual_methods() 
{ 
    var pet = Freezable.MakeFreezable<WithNonVirtualMethod>(); 
    pet.Name = "Rex"; 
    pet.NonVirtualMethod(); 
} 
 
[Fact] 
public void Freezable_should_throw_when_trying_to_freeze_classes_with_nonVirtual_setters() 
{ 
    var exception = Assert.Throws<InvalidOperationException>( () => 
        Freezable.MakeFreezable<WithNonVirtualSetter>() ); 
    Assert.Equal( 
        "Property NonVirtualProperty is not virtual. Can't freeze classes with non-virtual properties.", 
        exception.Message ); 
} 

If we run the tests the first one will pass, the second one will fail. Is that a surprise? We don’t have any checking code in place, so when we encounter a non virtual member, we do nothing. that’s why we effectively ignored the NonVirtualMethod in the first test (which is the behavior we want), but we also ignored the non-virtual property setter in the second test, which is a no-no.

To make them pass, we need to actually implement the NonVirtualMemberNotification method, to throw an exception when it encounters a property setter. There’s no specific exception type we’re obligated to throw, so we’ll just throw InvalidOperationException as specified in our test.

Here’s the implementation:

public void NonVirtualMemberNotification(Type type, MemberInfo memberInfo) 
{ 
    var method = memberInfo as MethodInfo; 
    if(method!=null) 
    { 
        this.ValidateNotSetter( method ); 
    } 
} 
 
private void ValidateNotSetter(MethodInfo method) 
{ 
    if( method.IsSpecialName && IsSetterName( method.Name ) ) 
        throw new InvalidOperationException( 
            string.Format( 
                "Property {0} is not virtual. Can't freeze classes with non-virtual properties.", 
                method.Name.Substring( "set_".Length ) 
                ) 
            ); 
} 

Similar to ShouldInterceptMethod method MarshalByRefObject and Object classes are special cases, and by default DynamicProxy will just ignore them.

With this change, all our tests now pass.

Other than the two methods we already discussed, IProxyGenerationHook has one more method: MethodsInspected. It gets called, after all methods on proxied type have been inspected, so it is the last method to be called by proxy generator. It is useful in cases when you hold some precious resources needed by two other methods.
For example if our hook implementation asked some external service (like a WCF service or database) about what to do with non-virtual methods, MethodsInspected would be the place to close the connection and dispose of all resources that are no longer needed.

With this part we basically covered almost all of basics of Dynamic Proxy. In the next part we’ll discuss other kinds of proxies you can create with Dynamic Proxy (yes, there are a few). Then we’ll talk about more advanced scenarios, like mixins.

I’m still open for feedback, so if you feel I missed some important topic or should have expand on something let me know in the comments.

The code, as always, is here.

Technorati Tags: , ,

Castle Dynamic Proxy tutorial part V: InterceptorSelector, fine grained control over proxying

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

Our Freezable library is starting to work quite well. However, there are still few glitches we need to polish. First of all, take a look at following screenshot from our sample application.

dptutorial_5_app_before

We have the support for interception and logging in place, but currently it’s an all or nothing scenario. We started with intercepting every single method. Then we decided to lower the overhead, and intercept only property setters. Neither of these solutions is perfect.
The first one allowed us to be more flexible. We could log all methods, ensure state immutability of the others, and if we had more interceptors, specific to some subset of methods, we could use them too. The downside of that approach was, that each interceptor was called for each method.
To remedy that, we used ProxyGenerationHook to choose only the methods we wanted to intercept. That cut it, but only partially. We still have every interceptor being called for each and every of those methods we decided to intercept.
What we’d really want, is a more fine grained control, that allows us to not only say which methods we want to intercept, but also with which interceptors.
First to do that, we need to introduce some changes to out project. For now, Logging interceptor was the one that kept count of all its invocation. Since we no longer want to have each interceptor called each time a method is intercepted, we will factor out the Count property to a new interface IHasCount, and make all interceptors implement it.
Also we will change the GetInterceptedMethodsCountFor to return a count for specific interceptor.

With that we can now specify our new requirements with a new test.

[Fact]
public void Freezable_should_log_getters_and_setters()
{
    var pet = Freezable.MakeFreezable<Pet>();
    pet.Age = 4;
    var age = pet.Age;
    int logsCount = GetInterceptedMethodsCountFor<CallLoggingInterceptor>( pet );
    int freezeCount = GetInterceptedMethodsCountFor<FreezableInterceptor>( pet );
    Assert.Equal( 2, logsCount );
    Assert.Equal( 1, freezeCount );
}

As expected, if we run the test now, it will fail. So how do we make it pass?
ProxyGenerationOptions class, has a property Selector of type IInterceptorSelector, that we’ll use to achieve that. The interface contains just one method:
dptutorial_5_iinterceptorSelector
The method gets called for each method being intercepted. It receives information about proxied type, the method, and an array of all interceptors registered with the proxy. It is expected to act upon this information and return these interceptors it wishes to be used for the method. Also, while ProxyGenerationHook’s ShouldInterceptMethod method gets called once, when generating proxy type, InterceptorSelector’s SelectInterceptors method is called for each instance of that type, just before the first call to that method.

So, what we need is to inspect the given method to see if it is a property setter and if it is not, not return the FreezableInterceptor.

public class FreezableInterceptorSelector : IInterceptorSelector
{
    public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
    {
        if (IsSetter(method))
            return interceptors;
        return interceptors.Where( i => !( i is FreezableInterceptor ) ).ToArray();
    }
 
    private bool IsSetter( MethodInfo method )
    {
        return method.IsSpecialName && method.Name.StartsWith( "set_", StringComparison.Ordinal );
    }
}

We also need to change Freezable.MakeFreezable method to actually make use of our new FreezableInterceptor.

private static readonly IInterceptorSelector _selector = new FreezableInterceptorSelector();
 
public static TFreezable MakeFreezable<TFreezable>() where TFreezable : class, new()
{
    var freezableInterceptor = new FreezableInterceptor();
    var options = new ProxyGenerationOptions(new FreezableProxyGenerationHook()) { Selector = _selector };
    var proxy = _generator.CreateClassProxy(typeof(TFreezable), options, new CallLoggingInterceptor(), freezableInterceptor);
    return proxy as TFreezable;
}

If we run the tests however, they will all pass, except for the new one. That is because we still select for interception only property setters. We need to update our FreezableProxyGenerationHook. To demonstrate how selector and proxy generation hook work together we’ll instruct the hook to not intercept methods, only properties. Here’s the updated code:

public bool ShouldInterceptMethod(Type type, MethodInfo memberInfo)
{
    return memberInfo.IsSpecialName &&
           ( IsSetterName( memberInfo.Name ) ||
             IsGetterName( memberInfo.Name ) );
}
 
private bool IsGetterName( string name )
{
    return name.StartsWith( "get_", StringComparison.Ordinal );
}
 
private bool IsSetterName( string name )
{
    return name.StartsWith("set_", StringComparison.Ordinal);
}

And the test to check if this actually works:

[Fact]
public void Freezable_should_not_intercept_methods()
{
 
    var pet = Freezable.MakeFreezable<Pet>();
    pet.ToString();
    int logsCount = GetInterceptedMethodsCountFor<CallLoggingInterceptor>(pet);
    int freezeCount = GetInterceptedMethodsCountFor<FreezableInterceptor>(pet);
 
    // base implementation of ToString calls each property getter, that we intercept
    // so there will be 3 calls if method is not intercepter, otherwise 4.
    Assert.Equal(3, logsCount);
    Assert.Equal(0, freezeCount);
}

There’s one not immediately obvious thing about that test. We check if we can intercept ToString method. In this particular case we get to decide, if we want that method intercepted or not. However if you set a breakpoint in the ShouldIntercept method, you’ll notice, that we don’t get asked that question for any other virtual method inherited from System.Object (GetHashCode, Equals).
That is because DynamicProxy not allows you to intercept System.Object’s (or System.MarshalByRefObject’s) methods, unless they’re overridden in the proxy type (or in any of its base types). Since Pet class does override ToString, we get the opportunity to intercept this method, whereas all other methods are not overridden so we can’t proxy them.

Here, for comparision is the screenshot from our application after introducing those changes:

dptutorial_5_app_after

The code is here.

Technorati Tags: , ,

Castle Dynamic Proxy tutorial part IV: breaking hard dependencies

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

In the last part of the tutorial we created a method GetInterceptedMethodsCountFor that I promised I’ll talk about soon. While we’re at it, we’re going to fix another design flaw of our Freezable class.

To do its work, it holds a hard reference to each and every freezable object it creates. This is obviously not a big deal if you create only a handful of freezable objects that are we want to be alive for the entire time the application is running.

private static readonly IDictionary<object, IFreezable> _freezables = new Dictionary<object, IFreezable>();

However, in most cases the objects we create are transient, and we create a lot of them. Looking at it from this perspective – we have a memory leak. Freezable class holds a reference to the objects, so garbage collector can not collect them and reclaim the memory they occupy, even though we may not use these objects ever again.

So how do we fix it? For now we’ll use evil hack I introduced in GetInterceptedMethodsCountFor method in the last part. Ultimately, we’re arrive at much nicer solution when we talk about mixins. But let’s not get ahead of ourselves.

If you took a look at the code from the previous part, the method is implemented as follows:

private int GetInterceptedMethodsCountFor(object freezable)
{
    Assert.True(Freezable.IsFreezable(freezable));
 
    var hack = freezable as IProxyTargetAccessor;
    Assert.NotNull(hack);
    var loggingInterceptor = hack.GetInterceptors().
                                 Where(i => i is CallLoggingInterceptor).
                                 Single() as CallLoggingInterceptor;
    return loggingInterceptor.Count;
}

The evil hack is based on the fact, that each proxy generated by Castle Dynamic Proxy framework implements an IProxyTargetAccessor interface. If you take a look at how it looks, it has two getter methods:

dptutorial_4_IProxyTargetAccessor

DynProxyGetTarget returns the proxies object. In our case the proxied object is the proxy itself, as we can prove with the following test

[Fact]
public void DynProxyGetTarget_should_return_proxy_itself()
{
    var pet = Freezable.MakeFreezable<Pet>();
    var hack = pet as IProxyTargetAccessor;
    Assert.NotNull(hack);
    Assert.Same(pet, hack.DynProxyGetTarget());
}

This is logical if you consider how DynamicProxy creates class proxies. It does so by creating a subclass of proxied type. The whole interception magic happens in overridden virtual methods and the methods of actual intercepted type are called via base.MyMethod(args). That’s why IProxyGenerationHook contains a method that allows you to act upon methods that are not virtual and hence can not be intercepted. We’ll use this feature in forthcoming part of the tutorial.

The other method, GetInterceptors, returns the interceptors associated with given proxy. We can use this method to obtain the proxy interceptors without keeping any hard reference to it.

So out task for this part of the tutorial is to break the need for hard reference the Freezable class holds to freezable objects. We state the requirement with the following test:

[Fact]
public void Freezable_should_not_hold_any_reference_to_created_objects()
{
    var pet = Freezable.MakeFreezable<Pet>();
    var petWeakReference = new WeakReference(pet, false);
    pet = null;
    GC.Collect();
    Assert.False(petWeakReference.IsAlive, "Object should have been collected");
}

If you run this test now, it will fail (go on, see for yourself, don’t get my word on it).

Now let’s factor out the dependency with out new found tool. First we refactor IsFreezable method, to the following.

public static bool IsFreezable(object obj)
{
    if (obj == null)
        return false;
    var hack = obj as IProxyTargetAccessor;
    if (hack == null)
        return false;
    return hack.GetInterceptors().Count(i => i is IFreezable) > 0;
}

If we run out tests, the old tests will pass (great, we didn’t break anything), but the new test, will still fail, as we have two more methods to refactor. Let’s now go to the IsFrozen method. I’m going to cheat here however. While implementing the method, I noticed that there’s a portion of code that each method in the class will require, so I factored it out, to another method. With that, here’s changed code:

public static bool IsFreezable(object obj)
{
    return AsFreezable(obj) != null;
}
 
private static IFreezable AsFreezable(object target)
{
    if (target == null)
        return null;
    var hack = target as IProxyTargetAccessor;
    if (hack == null)
        return null;
    return hack.GetInterceptors().FirstOrDefault(i => i is FreezableInterceptor) as IFreezable;
}
 
public static bool IsFrozen(object obj)
{
    var freezable = AsFreezable(obj);
    return freezable != null && freezable.IsFrozen;
}

We added the AsFreezable method that returns either IFreezable implementation associated with given object, or null, if there isn’t any.

We have two more methods to refactor:

public static void Freeze(object freezable)
{
    var interceptor = AsFreezable(freezable);
    if (interceptor == null)
        throw new NotFreezableObjectException(freezable);
    interceptor.Freeze();
}

Freeze implementation is still very simple. The MakeFreezable<TFreezable>() method only puts newly created objects into the dictionary, so we can safely remove it from that method. We can now also delete the dictionary field, as it’s not used anymore.

If you run the tests now, you’ll see that they all pass, including the newly added one.

dptutorial_4_tests_passed

The code, including tests, is here.

Final words

Even though we fixed the memory leak issue, it still is not the best solution. That said, IProxyTargetAccessor is a useful interface and it’s good to know that its there when you need it, but most of the time you don’t need it and in almost every case there’s a better way to accomplish your goal, without using the interface.

It’s mostly intended for use in low level, framework infrastructure code, and if used anywhere else you should treat it as a warning sign.

Technorati Tags: , ,

Castle Dynamic Proxy tutorial part III: Selecting which methods to intercept

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

We’ll start by updating our CallLoggingInterceptor class, so that we can use it in tests. What we need from it, is to enhance its functionality, so that it not only logs (to the Console) the calls, but also keeps a count of calls. To do that we add a property called Count, which gets incremented each time a method is called. It’s a trivial code, so I’ won’t show it here.

With that, we can now write our first test. We want property setters to fire tests for object freezability. Getters are safe in this regard and test always passes, so it’s an unnecessary overhead. We want our getters to not get intercepted, so let’s write a test for that.

[Fact]
public void Freezable_should_not_intercept_property_getters()
{
    var pet = Freezable.MakeFreezable<Pet>();
    Freezable.Freeze(pet);
    var notUsed = pet.Age; //should not intercept
    var interceptedMethodsCount = GetInterceptedMethodsCountFor(pet);
    Assert.Equal(0, interceptedMethodsCount);
}

Let us not concern ourselves with GetInterceptedMethodsCountFor method just yet. For now let’s only say that it just does what its name suggests. We’ll inspect its implementation later. Now, we run the test, and – as expected, it fails.

dptutorial_3_getter_failed_test

So how do we make it pass? What we need is some kind of mechanism that will enable us to choose, which methods we want to intercept, and which we don’t. Fortunately Dynamic Proxy enables that. It exposes a hook that enables us to plug in into its proxy generation pipeline, in form of… IProxyGenerationHook interface (you wouldn’t guess, would you?).

dptutorial_3_IProxyGenerationHook

Two really interesting methods are NonVirtualMemberNotification, that enables us to act, when user wants to proxy a type that has some non-virtual methods i.e. methods we can’t intercept. We’ll concentrate on that method in the next part of the tutorial.

What we need right now is ShouldInterceptMethod method, that enables us to decide whether we want to intercept a method or not. We know all we need, so let’s add a new class to our project, and implement the method, leaving two other methods empty just for now.

public class FreezableProxyGenerationHook:IProxyGenerationHook
{
    public bool ShouldInterceptMethod(Type type, MethodInfo memberInfo)
    {
        return !memberInfo.Name.StartsWith("get_", StringComparison.Ordinal);
    }
 
    public void NonVirtualMemberNotification(Type type, MemberInfo memberInfo)
    {
    }
 
    public void MethodsInspected()
    {
    }
}

OK, we have our proxy generation hook, but how do we actually hook into the pipeline? To do this we need to provide our hook to proxy generation method, so a good place to look is CreateClassProxy method on our generator. Indeed it has quite a few overloads.

dptutorial_3_CreateClassProxyOverloads

Some of them take additional parameter of type ProxyGenerationOptions, and this is exactly what we need. We will examine ProxyGenerationOptions class in details as we move through this tutorial, because it’s a very important class in advanced proxy related scenarios. Basically, as its name implies it’s a container for various options related to proxy generation process. As such it’s also used to pass out proxy generation hook to the proxy generator. We can pass our FreezableProxyGenerationHook as a constructor argument to ProxyGenerationOptions. We also need to cast generated object back to its type,as we’re using a non-generic version of CreateClassProxy now.

public static TFreezable MakeFreezable<TFreezable>() where TFreezable : class, new()
{
    var freezableInterceptor = new FreezableInterceptor();
    var options = new ProxyGenerationOptions(new FreezableProxyGenerationHook());
    var proxy = _generator.CreateClassProxy(typeof(TFreezable), options, new CallLoggingInterceptor(), freezableInterceptor);
    _freezables.Add(proxy, freezableInterceptor);
    return proxy as TFreezable;
}

With this change we can now see if our test passes…

dptutorial_3_getter_passed_test

…and it does, along with all other. Great. Now, our implementation takes care of property getters but how about all the other methods? Well they get intercepted too, which is not the desired behavior. To fix that, we need to slightly alter our ShouldInterceptMethod method to intercept only property setters

public bool ShouldInterceptMethod(Type type, MethodInfo memberInfo)
{
    return memberInfo.Name.StartsWith("set_", StringComparison.Ordinal);
}

(I did this in a test first manner, but I won’t bore you with screenshots of failed/passed tests. The tests however are in the attached code).

If we run the program now, we’ll see that only setters get intercepted.

dptutorial_3_program

In the next part of the tutorial we’ll take care of cases when we can’t ensure objects state is never changed, and we’ll discuss the implementation of GetInterceptedMethodsCountFor method from our tests.

In the meantime, if you have any questions use the “leave comment” feature of this blog, or ping me via GTalk, email or Skype.

Code is here.

Technorati Tags: , ,

DynamicProxy IInterceptorSelector support implemented (again)

After my first attempt at making IInterceptorSelector support in DynamicProxy actually work, there has been a discussion on castle-dev discussion group, about the implementation, its implication and features. To make long story short (find and read the thread if you’re interested) I set up to redo the implementation, moving most of the code that was generated at runtime into another, statically compiled class. Finally yesterday I had some time to actually start working on the implementation, but fixing bugs with code-gen at 1am proved to not be my strongest skill, so I finished the implementation today. Funny thing is, I found the bug without even turning on the computer. I just woke up fresh in the morning, I thought about what could be the cause, and in no time it came to me. But I digress.

I’m posting the patch to donjon, and hopefully someone will review it and apply soon this time, so in a couple of days you’ll be able to use this functionality. I’ll blog about it in one of forthcoming parts of my DynamicProxy tutorial.

And here’s a small teaser:

DynamicProxy generated code

 

Technorati Tags: ,

Castle DynamicProxy IInterceptorSelector implementation

I just got this test pass:

[Test]
public void BasicCase()
{
    ProxyGenerationOptions options = new ProxyGenerationOptions();
    options.Selector = new AllInterceptorSelector();
    var target = this.generator.CreateInterfaceProxyWithTarget(
        typeof(ISimpleInterface), 
        new SimpleClass(),
        options,
        new NoopInterceptor() ) as ISimpleInterface;
    Assert.IsNotNull( target );
    target.Do();            
}

And here’s how Do proxy method looks like in Reflector:

interceptorSelectorMethodInReflector