There are extensions for ninject that handle things like xml configuration.
I'd be careful about mixing up the programming bits from the config a la Spring XML config though - there's no need to move to XML config just to allow people to configure things in a .config file. I suggest reading an XML config section loader that serializes in a class that expresses that at a higher level instead.
You'd use the metadata mechanism on your Binding registrations and then indicate how to filter the set of tasks based on that.
e.g., repurposing @Ian Davis's answer (go read it and upvote it now!):
string metaDataKey = "key";
kernel.Bind<IWeapon>().To<Shuriken>().WithMetadata(metaDataKey, true);
kernel.Bind<IWeapon>().To<Sword>().WithMetadata(metaDataKey, false);
kernel.Bind<IWeapon>().To<Knife>();
bool? theOneIWant = null; // or true or false - i.e., the distillation of what your config says
Func<IMetadata> myConfigSaysIWantOneLikeThatPredicate= metadata =>
metadata.Has(metaDataKey) == theOneIWant != null
&& metadata.Get<bool>(metaDataKey) == theOneIWant.Value
var weapons = kernel.Get<IEnumerable<IWeapon>>( myConfigSaysIWantOneLikeThatPredicate );
// the above will generate a single item given the bindings above, but you get the picture - this generates an arbitrary length list
foreach(var weapon in weapons)
weapon.Fire();
If all you're looking for is to be able to name them, there's a shorthand replacement for WithMetadata
called Named()
and an overload for .Get<T>()
with a name string parameter, which would let you achieve @dave thieben's simplicity without your invocations being hardwired to Type names.
EDIT: Sample, see comments:
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace ninjectmess
{
public class Class1
{
Some junk classes
public interface ITask
{
}
public class Aasdsdaadsdsa : ITask
{
}
public class Bdsadsadasdsadsadsa : ITask
{
}
public class Cddsadasdsadasdas : ITask
{
}
the actual test
[Fact]
public void TestMethod()
{
var k = new StandardKernel();
k.Bind<ITask>().To<Aasdsdaadsdsa>().Named( "A" );
k.Bind<ITask>().To<Bdsadsadasdsadsadsa>().Named( "B" );
k.Bind<ITask>().To<Cddsadasdsadasdas>().Named( "C" );
var wanted = new string[] { "A", "C" };
var tasks = k
.GetAll<ITask>( metadata => wanted.Contains( metadata.Name ))
.ToList();
Assert.Equal( 2, tasks.Count );
tasks.ForEach( Console.WriteLine );
}
}
}
>(commands); foreach (IWeapon weapon in weapons) weapon.Fire(); But I have to: foreach (string command in commands) { weapon = kernel.Get(command);
weapon.Fire();
}
>( binding=>commands.Contains(binding.Metadata.Name))`. Not sure if you need to create a Request, but if you did, it'd be easy to wrap it up as an extension. If you dont have it in 10 hrs, I'll be sitting on intellisense and will put in the real incantation then.
– Ruben Bartelink Feb 09 '11 at 22:00>(binding => args.Contains(binding.Name));
– Twisted Feb 10 '11 at 14:06