Behaviour Injection

Dependency Injection

I have recently caught up to date with common patterns and practices today. One I was looking at was Dependency Injection. Simply put, it's amazing. I can not think of a single better way to make your code maintainable. I recommend that everyone who hasn't yet had time to tinker with it download a toolkit and see what it can do for you.

I then started thinking about the practical implications of dependancy injection. Sure, it's great for creating objects with static operations (e.g. weapon.Attack()), but how can I apply several dependencies to one object's member? For example, if I were to make an IDE one would need to have a dependancy for each designer plugin so that when the user right clicks each gets a chance to add something to the context menu.

Behaviour Injection

I then came up with the idea of behaviour injection. It works a lot like dependancy injection, except that you can inject more than one dependancy into an object's member. If we had a class as follows:

public abstract class DesignerContextMenu
{
   [BehaviourTarget("/editing/design/contextMenu#fill")]
   public abstract void Fill(ContextMenu menu, object target);

   public void Show(object target)
   {
      ContextMenu menu = new ContextMenu();
      Fill(menu, target);
      menu.Show();
   }
}

We should be able to apply behaviours such as:

public class PropertiesWindow : IdeWindow
{
   public override void RegisterBehaviours()
   {
      BehaviourSystem.Register(this);
   }

   [Behaviour("/editing/design/contextMenu#fill")]
   public void Fill(ContextMenu menu, object target)
   {
      if(!(target is ProjectPropertiesDesigner))
      {
         menu.MenuItems.Add("Properties");
      }
   }
}

public class FormDesigner : Designer
{
   public override void RegisterBehaviours()
   {
      BehaviourSystem.Register(this);
   }

   [Behaviour("/editing/design/contextMenu#fill")]
   public void Fill(ContextMenu menu, object target)
   {
      if(target is FormDesigner)
      {
         menu.MenuItems.Add("Lock Controls");
      }
   }
}

Finally, we would then have our root designer that would:

public class Designer : Control
{
   protected override OnMouseDown(object target, MouseEventArgs args)
   {
      DesignerContextMenu menu = BehaviourSystem.Create<DesignerContextMenu>();
      menu.Show(this);
   }
}

The code was written in notepad, so don't expect it to compile , but it does bring the point across.

Implications

The main problem with this system is that you have no idea in which order the behaviours will be called: although in my honest opinion your system should really be designed in a way that it doesn't really matter.

In any case, this was a quick hashing out of thoughts in the public domain, does anyone have any comments?

posted @ Wednesday, July 30, 2008 5:33 PM

Print
«November»
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345