LA.NET [EN]

May 30

Well, not really…

As you surely know, you cannot have mutiple inheritance in .NET. That really sucks. Yes, I agree that multiple inheritance might bring several problems but when applied correctly,  it really helps. Don”t believe me? Ok, take a look at WTL.

Back to .NET…Since we can”t use multiple inheritance, we end up defining several interfaces and injecting classes that implement the generic boilerplate code for those interfaces. With Windsor (or any other existing container), we”re able to reduce the necessary code to instantiante an object but we still need to implement all the members of the interfaces that our base class extends. In practice, implementing this methods means redirecting those calls to instance fields that are initiated through injection.

Today I had some free time and I”ve decided to play with Postsharp. One of the things you can do with it is replace this manual tedious work and get all those interfaces implemented automatically during compilation. To achieve this, we need to create a new custom (or should I say, derived) CompositionAspect attribute and apply it the class we want to extend.

Since I really didn”t had much time, I decided to implement something simple and really chose a bad example: the INotifyPropertyChanged interface. I say unfortunately because,as you”ll see,I”ve ended up firing the event from a field change and this made me develop and additional attribute that is used for intercepting field changes (this was necessary due to the way events work). anyway, let”s get started. The first thing we need is a general implementation for the interface. Here”s one good enough for demo code:

public class PropertyChangedGeneralNotification : INotifyPropertyChanged
{
        private readonly Object _firingObject;

        public PropertyChangedGeneralNotification(Object firingObject)
        {
            _firingObject = firingObject;
        }
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if( PropertyChanged != null)
            {
                PropertyChanged(_firingObject, e);
            }
        }
}

This interface defines only one member: an event. My initial idea was to really build a simple class that had only the necessary event. Then, the final injected class would simply fire it. Unfortunately, you cannot do that since you can only “use events like delegates” on the class they”re defined (I”m sure there really is a good reason on why there is such a strong relationship between events and the classes where they are defined, but I still haven”t found a definitive answer for it – btw, if you know, please put it in the comments).

Anyway, that”s why I ended up adding the OnPropertyChanged method and added a constructor which receives a reference to the object that is being injected (we need this because when we fire the event we must pass a reference to that class as the first parameter to the method that handles the event).

Ok, Now we need to build the class that is responsible for injecting the previous generic class. To achieve that, we need to create a new CompositionAspect derived class. This class must be serializable and we can override several methods to control the output of the class to which the attribute is going to be applied. Here”s the code I”ve got:

[Serializable]
public class AOPInterfaceInjectionAttribute : CompositionAspect
{
        public override object CreateImplementationObject(InstanceBoundLaosEventArgs eventArgs)
        {
            return new PropertyChangedGeneralNotification(eventArgs.Instance);
        }

        public override Type GetPublicInterface(Type containerType)
        {
            return typeof (INotifyPropertyChanged);
        }

        public override CompositionAspectOptions GetOptions() {
            return CompositionAspectOptions.GenerateImplementationAccessor;
        }
}

The GetPublicInterface method is responsible for returning the type of the public interface that the injected class will implement. The CreateImplementationObject method must return an object that implements the referenced interface (in this case, we”re returning an instance of the general class we”ve implemented in the previous snippet). Notice that we”re using the InstanceBoundLaosEventArgs to get a reference to the instance that is being injected and passing it to our general class so that the correct reference is passed when the PropertyChanged event is fired.

The final thing you should note is the override of the GetOptions method. We”re saying that in this case we should be able to get a reference to the class that is injected. This means that our “injected” class will also implement the IComposed<T> interface, which has methods that will let us get a reference to that object.

Applying this attribute to an existing class is all that is necessary for exposing the interface:

[AOPFieldChangedInjection]
public class Student
{
        public String Name { get; set; }
        public Int32 Age { get; set; }
}

Now, the only thing that is missing is generating the event. In this case, I though it would be fun to go ahead and create an attribute that intercepts field calls (ok, I know that this is not really the best approach, but at least I can have some more fun and learn more about the platform). When we need to intercept field calls, we can extend the OnFieldAccessAspect class. Here”s what I”ve done:

[Serializable]
public class AOPFieldChangedInjectionAttribute : OnFieldAccessAspect
{
       public override void OnSetValue(FieldAccessEventArgs eventArgs)
       {
           var shouldFireChangedEvent = !eventArgs.ExposedFieldValue.Equals(
                                             eventArgs.StoredFieldValue);
           //call base to change the value of the field
           base.OnSetValue(eventArgs);
           //check if event should be fired
           if (shouldFireChangedEvent)
           {
               InstanceCredentials credentials =
eventArgs.InstanceCredentials;
               var composedInteface = (IComposed<INotifyPropertyChanged>) (eventArgs.Instance);
               var evtHandler = (PropertyChangedGeneralNotification) composedInteface.GetImplementation(credentials);

               if (evtHandler != null)
               {
                   evtHandler.OnPropertyChanged(new PropertyChangedEventArgs(eventArgs.FieldInfo.Name));
               }
           }
       }
}

Overriding the OnSetValue is necessary if you want to intercept a write operation. I start by comparing the old value with the new value that is being saved to the field before callilng the base”s method. The interesting part is the code necessary for firing the event. We start by getting the credentials. This is a nice concept that is used to prevent access from any code to the implementation code; only code that knows the credentials can access the implementation of the interface.

Notice that in this case we end up casting the interface to the class so that we can call the method that ends up generating the event (no, I can”t say that I like the previous code but I can live with it since I”m writing testing exploratory code). As you can see, we end up passing the name of the field instead of passing the name of the property (again, I said that my example was poor, right?)

What matters is that now it”s really easy to reuse our generic code, as you can see from the next class (which should really be in a different assembly from the one that showed the previous code):

[AOPInterfaceInjection]
[AOPFieldChangedInjection]
public class Student
{
        public String Name { get; set; }
        public Int32 Age { get; set; }
}

After compiling, the previous class will implement interfaces INotifyPropertyChanged and IComposed<INotifyPropertyChanged> and you”ll get events fired when you change any of its properties.

There are still lots of stuff you can do with Postsharp. My first impressions are good: with this platform it”s really easy to apply AOP to our projects. I”m still not convinced that this is best thing in thw world, but I”ll keep playing with it and see how it reduces the code that I need to write on my day-to-day scenarios.

4 comments so far

  1. Damon Wilder Carr
    6:26 pm - 6-4-2008

    Great post. Your obviously highly accomplished in these areas.

    I would only add that one emerging pattern to achieve this with far less pain and ”uncertainty” in regard to future support and maintainability is the pattern of:

    ”Use Extension Methods with Qualified Interface Type for Multi-inheritance Style Extension”

    I have seen this written up by a few and I have used this myself (before really even thinking much about it) since I got mt hands on C# 3.0 beta X whatever that was..

    public interface IDomainQueryService {

    }

  2. Damon Wilder Carr
    6:58 pm - 6-4-2008

    Sorry I accidently submitted. To continue (one arbitrary example – the pattern not the types I use are the idea):

    publlic interface IDomainServiceResolver {

    TTypeService Resolve(params Predicate[] resolveConditions) where TTypeService : IServiceProvider
    }

    That”s it. We extending this using extension and IDomainServiceResolve (or IServiceProvider) as a nice option moving forward.

    The idea is create an interface with (typically) 1 core element to the functionality. For file services it could be the path, for XML is could be the Stream for the DOM, for images it could be a SystemDrawing.Image….

    So for this to work extensions work off an instance, so we need an instance of any IServiceResolver. Here is a simple example assuming it gives us a nice instance of some IDomainServiceResolver :

    Predicate predCondition = cus => cust.IsActive;

    var customerProjection =
    Resolver.For.Get<CustomerRepository>(predCondition );

    Ok fine… What if we have addition needs on the interface? Such as for an ability to see if the service is available?

    public static TTypeService IsAvailable(this TTypeResolver providerTarger) where TTypeResolver : IServiceProvider {

    return providerTarget.ServiceExists(x => typeof(TTypeService));

    }

    then

    IQueryService serviceInstance = Resolver.For.IsAvailable();

    if (serviceInstance.Equals(Resolver.NullService))
    /// do whatever…

    }

    I am writing this from memory so I may have missed a . or a ( somewhere. If you like I can send you a more compelling example we use almost every day using this as a factory (it”s cool I think):

    var _sb = true.InstanceOf(); or:

    StringBuilder _sb = true.InstanceOf();

    or

    var _sb = typeof(StringBuilder).InstanceOf(); (you get the idea…)

    as true is an instance of bool this extension (instanceOf) simply extends the ”bool” interface….

    Thanks,
    Damon Wilder Carr

  3. Luis Abreu
    8:57 pm - 6-4-2008

    Good example Damon.

    Yeah, if you have a simple example, i”d love to play with it 🙂

  4. Oftenvisiter
    3:39 am - 3-16-2010

    Digging up an old article, but I find myself here, so hopefully this is useful to more than just me.

    Events are really callback functions (or pointers to functions) which reside within a class. But every function inside a class has a hidden parameter you never see. And that parameter is “this” in C++/C# and “Me” in vb. And this leads us with a problem.

    If that callback where to be copied among different classes, it would have a different function signature for each class. And then the generated IL would have to be altered for each class/place it is being injected into based on determining what the class is (if that is even guaranteed possible for every type of class in .NET, considering reflection).

    PostSharp (now sharpcrafters) is simply not a compiler, and therefore should not do something so evasive. In doing so, it could open up security holes and other issues, if this is possible and within scope.