Combined Aspects

by Gael Fraiteur, 29 January 2007
I had a new interesting discussion, this time with John Vanspronssen. I'm not sure I've understood all he has in mind, but I was challenged by the idea of 'composed aspects', that is, aspects composed of many transformations. In order to avoid confusion with object composition, I chose to rename this combined aspects. I first planned to implement this in a later phase, but this discussion just excited me to do it... and it's done! So what's a composed aspect? As I said, it is an aspect composed of many sub-aspects. John gave the binding aspect as an example. This aspect 'simply' raises an event OnPropertyChanged. Say I have the following base code:
interface IBindable
{
event EventHandler OnPropertyChanged;
}

[Bindable]
class MyClass
{
private int field1;

public int Field1
{
 get { return field1; }
 set { field1 = value; }
}
}
The post-compiled code should look like this:
class MyClass : IBindable
{
private int field1;

public event EventHandler OnPropertyChanged;

public int Field1
{
  get { return field1; }
  set
  {
      field1 = value;
      if (this.OnPropertyChanged != null)
      {
          this.OnPropertyChanged(this, EventArgs.Empty);
      }
  }
}
}
There are two sub-aspects combined in the Binding aspect:
  1. A CompositionAspect: adding the IBinding interface and its implementation.
  2. An OnMethodBoundaryAspect applied to the method set_MyProperty method: raising the OnPropertyChanged method. If there were more than one property, there would be one aspect of this type for each writable property.
The aspect implementation has less than 100 lines of code including blank ones. I don't copy it in this post, but you can see it online. The following points are interesting:
  1. The class BindableImplementation is the implementation of the IBindable interface. This type is composed inside the target the AddBindableInterfaceAspect aspect, which is derived from CompositionAspect.
  2. The aspect OnPropertySetAspect is derived from OnMethodBoundaryAspect and implements only the OnExit method. The only thing it does is to retrieve the implementation of IBindable for this instance (that is, the composed BindableImplementation object) and raise the OnObjectChanged event.
  3. The class BindableAttribute is the principal class and the only public one. It is derived from CombinedAspect and implement the method ProvideAspects. This method is the most interesting. First it adds the AddBindableInterfaceAspect to the type, then it scans all the writable properties in this type and applies the OnPropertySetAspect to them. This method is of course executed at compile time.
A good question is: how can the OnProperySetAspect retrieve the implementation of the IBindable interface? It took me at least two nights to answer. Let me ask the question more formally: suppose that an object is composed of different behaviours (composed objects and aspects). How can these different behaviour exchange information between themselves? I think that this problem should ideally be solved by the platform, that is, by .NET itself. The platform should ideally have a concept that 'an instance is the friend of another'. If the developer chooses to apply an aspect to a class, it is legitimate to give this aspect more permissions on the target type than the permissions we want to give to everybody ('public' access). And it is not possible for the aspect to have access only to protected data, since the aspect is not derived from the target type. The solution I designed is to rely on credentials. Each instance (at least each instance of a type that wants to 'share' something) has its own 'secret' called credentials. The can give the credentials to some other instance. Then, this instance can use these credentials to get access to some 'protected' data (but here protected by these credentials, not by restriction of visibility). This mechanism is currently only used to retrieve the instance implementing an interface that has been composed by CompositionAspect. Composed types may optionally implement the interface IComposed , where T is the composed interface (IBindable in our example). This interface has a single method GetImplementation... that requires the credentials. How can the OnPropertySetAspect know the credentials? These are passed through the event arguments (MethodExecutionEventArgs). That is, aspects will receive the credentials to access 'protected' data of the aspected instance. But only of this instance! I've said this was designed, but this is not completely implemented. In the version I put online tonight, credentials are not yet checks. And there are still problems if you try to apply the same custom attributes on a class and its parent class. This will be solved during the next week or two. Enjoy! Gael

The promised features are available

by Gael Fraiteur, 20 January 2007
The features that I promised in the last post are already available. Please read the release announcement on postsharp.org.

Current design problems with PostSharp code weavers

by Gael Fraiteur, 15 January 2007
As I wrote two posts ago, I discovered some design problems with both PostSharp aspect weavers: the low-level one and Laos, the high-level one. I have written a log of improvement proposals in the PostSharp Roadmap: Since most are breaking changes, I would like to implement them before Beta 1. I know some users already rely on these features. That's why I invite them to send feedback to share their opinion. Please use the add comment feature of the website for this (not this blog post). Thank you. Gael

PostSharp Video

by Gael Fraiteur, 14 January 2007
I've just finished the first demonstration video about PostSharp. It replaces the previous Flash demonstration. The most difficult was to raise above timidity. If someone can record the audio track with a better English accent, he is welcome to do the job :-). Gael

Laos to a new design cycle?

by Gael Fraiteur, 9 January 2007
We had two important discussions today with Andre, one about PostSharp Laos, the other about the 'freeze' dates. The discussion about PostSharp Laos, together with other doubts I have, suggests me to send PostSharp Laos in a new design cycle. I really need more feedback like the one of Andre today. I need to know what are the problems encountered in situation. These discussions may have on the design of PostSharp Laos, at least on the public interface. My initial plan was to freeze all public interfaces with the Beta 1 release (which has been delayed because Wang saw an integration problem with VB.NET). But it seems that some parts of the code are more mature than others, and PostSharp Laos seems to belong to the second group. So that's what I decided:
  1. The public interface of all core components (excluding eventually Laos and the MSBuild integration) will be frozen after the Beta 1 release. So people that started to use these interfaces (I know there are) can sleep on both ears.
  2. The specifications of PostSharp Laos will be frozen with Beta 2.
Remember that I really need your feedback to close the specs. The quality of the design depends also on your feedback!! BTW, I plan to open the public interface of the weaver of PostSharp Laos, so it will be possible to implement new base custom attributes using the low-level APIes and using the infrastructure of Laos. This will be after Beta 1, however. I am still hesitating about the right moment to introduced the planned but missing features of PostSharp, principally:
  • the state sharing and
  • the possibility to add aspects programatically at compile-time (and not only declaratively using custom attributes), of course using solely System.Reflection and PostSharp.Laos (no low-level API).
Good night to all people living in my time zone, Gael

Blog Tag

by Gael Fraiteur, 5 January 2007
Olaf got me in the game. He decided to loose my time. For the things you know, my personal marketing material is on http://gael.fraiteur.net. But shhht, that's for headhunters! Five things you don't know about me?
  1. I have lived 3 years in ex-Zaire (current R.D. Congo). How not to get bored when school ends at 1 PM? At the age of 11, I felt too old to play the whole afternoon in the swimming pool. Hopefully my father brought a computer home and I could start... programming.
  2. I don't have any wisdom tooth. Maybe I am not wise enough.
  3. As Olaf, I don't have the driving license. The difference is that I am older (28) and have two children. And a wife, but I don't have to bear her.
  4. I got respected by my Czech colleagues when I started to speak as vulgarly as them. It took me three years of full immersion to reach this level of linguistic refinement.
  5. I know 'personally' really little bloggers. Less than five! So I have to tag people I don't even know.
I suppose these read my blog: Miha Markic, Alex Yakunin, JB Evain I would add Per but he does not blog... I just hope I will not get damned for having partially broken the chain!

Redesign of PostSharp Laos

by Gael Fraiteur, 2 January 2007
I took the last opportunity to change the public interface of PostSharp Laos. Hopefully, for most of you, the changes will be trivial and a find-and-replace will do the job. The old design was to pass a lot of parameter to each method like OnEntry or OnExit, for instance. Each piece of context (object instance, array of arguments, arrays of generic arguments, ...) was passed as a standalone parameter. This kind of design had serious drawbacks. The main is flexibility, i.e. forward compatibility. If I want to add a new information to the context, I have to add a new parameter... and break the public interface. Conversely, the new design often passes a single parameter, an object containing all information about the context. This makes Laos much event oriented. A join point is like an 'event' in the code and an advice is like an 'event handler'. For instance, the OnEntry method now looks like this: public override void OnEntry(MethodExecutionEventArgs eventArgs) It is really similar to event handlers written in the derived class, according to the design pattern recommended by Microsoft. I came to this idea when talking when Olaf. Aspect-oriented programming can really be seen as common event-oriented programming. It is 'just' another way to define 'events' in the code and to define event handlers. PostSharp Laos currently forces you to add the 'event handlers' at compile time, but one easily imagine extending it so that 'event handlers' can be added at runtime. What does that mean? That we get something very close to 'dynamic weaving'. But with a big difference: while event handlers can effectively be added at runtime, the events in themselves (i.e. the join points) have to be defined at compile time or at load time. That's for another time, but the current design of PostSharp Laos makes it very easy. Enjoy... and forgive the change in the public interface :-) Gael