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?