Geeks With Blogs

@moitoius
  • moitoius Warcraft II on my HTC Wizard (still waiting for the TyTN II), Apple eat your heart out... about 1686 days ago
  • moitoius getting my tytn II hopefully today! hold thumbs! about 1687 days ago
  • moitoius going to hillsong on the 22nd! yeah! about 1689 days ago
  • moitoius nearly home, ready for the weekend and ttf fun. about 1696 days ago
  • moitoius also trying my hand at ROAM landscapes. with geomorphs. in xna. hell yeah. about 1696 days ago
  • moitoius is very impressed with the twitter support in fring. about 1696 days ago

News This blog has moved to http://jonathan.dickinsons.co.za/blog.
Jonathan Dickinson Moved to: jonathan.dickinsons.co.za/blog

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 on Wednesday, July 30, 2008 5:33 PM C# , Behaviour Injection , Patterns and Practices | Back to top

Copyright © Jonathan Dickinson | Powered by: GeeksWithBlogs.net | Join free