If Sitefinity and Subsonic wasn't enough, enter Ninject. Go to their website to understand what its all about and I took their example and pulled out a bit further. Take this for instance in the warrior module. I wanted a swordsman, an archer and a samauri. I also wanted to attack Steve for landing a consulting gig downtown, so he was the intented target for my new ninject army.
First, I created an archer. Now before I go further, the example they gave on the ninject site wasn't going to fit what I wanted. I needed a "base" interface (IWeapon) then subsequent interfaces from there (IRangedWeapon and IMeleeWeapon) so enter IRangedWeapon with Fire (!!!!!) ...
namespace Ninject
{
public interface IRangeWeapon : IWeapon
{
void Fire(string target);
}
}
And now we need a weapon ...enter the Bow class
namespace Ninject
{
public class Bow : IRangeWeapon
{
void IRangeWeapon.Fire(string target)
{ Console.WriteLine("Right though {0}'s heart", target); }
void IWeapon.Hit(string target)
{ Console.WriteLine("Right though {0}'s heart", target); }
}
}
along with some extra attributes...(some are not explained in this example)
public class Range : Attribute { }
public class LongSword : Attribute { }
public class ShortSword : Attribute { }
public class LongRange : Attribute { }
And lets make an Archer class...
namespace Ninject
{
class Archer
{
[Inject, LongRange]
public IRangeWeapon Weapon
{ get; set; }
[Inject, LongRange]
public Archer(IRangeWeapon weapon)
{ Weapon = weapon; }
[Inject, LongRange]
public void Arm(IRangeWeapon weapon)
{ Weapon = weapon; }
public void Attack(string target)
{ Weapon.Hit(target); }
public void Fire(string target)
{ Weapon.Fire(target); }
}
}
In my module, I changed up the warrior module as such...
public override void Load()
{
Bind<IMeleeWeapon>().To<Dagger>().WhereMemberHas<ShortSword>();
Bind<IMeleeWeapon>().To<Kitana>().WhereMemberHas<LongSword>();
Bind<IRangeWeapon>().To<Shuriken>().WhereMemberHas<Range>();
Bind<IRangeWeapon>().To<Bow>().WhereMemberHas<LongRange>();
}
and finally, in the main program I ask for an archer...
namespace Ninject
{
class Program
{
const string PersonToAttack = "Steve";
static void Main(string[] args)
{
IKernel kernelWarrior = new StandardKernel(new WarriorModule());
Samurai warrior = kernelWarrior.Get<Samurai>();
Archer archer = kernelWarrior.Get<Archer>();
Swordsman swordsman = kernelWarrior.Get<Swordsman>();
warrior.Attack(PersonToAttack);
archer.Attack(PersonToAttack);
swordsman.Attack(PersonToAttack);
Console.ReadLine();
}
}
}
The result is total mayhem!
Poor steve...he never had a chance...
Ok, you're probably asking "So what?" Notice my module says WhenMemberHas<T> -- that tells Ninject to go do stuff. Because the property in Archer is set with the longrange attribute [Inject, LongRange] the kernelWarrior.Get<T> looks at the call finds that attribute and snags in the <Bow>. There's a bunch of different ways to use this, but hopefully that'll get you started with the million dollar "What else can this thing do?" :-D