运行时绑定:一个简单的任务运行器与ninject?

时间:2011-02-04 09:25:41

标签: ninject

我正在编写一个简单的任务运行器应用程序。

我有一堆实现ITask接口的类:

public interface ITask
{
   void Run();
}

我正在编写一个简单的控制台应用程序来创建ITasks的实例,然后在每个应用程序上调用Run()。任务实现使用构造函数注入,所以我想使用ninject。

我希望能够在运行时指定要运行哪些任务,以及因此要激活哪些ITask实现。

我在想我可以将具体类型放入我的app.config然后在运行时我可以获得ninject从中构建一个ITask数组。如果做不到这一点,我可以指定我想在命令行上运行的任务。

对我而言,这听起来像是ninject的一个相当直接的案例,但我一直无法找到如何从配置或字符串中绑定ninject。

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:6)

ninject有extensions来处理像xml配置这样的事情。

我要小心将配置和Spring XML配置中的编程位混合在一起 - 没有必要转移到XML配置只是为了允许人们在.config文件中配置东西。我建议阅读一个XML配置节加载器,它在一个类中进行序列化,而不是在更高级别表达。

您在绑定注册上使用metadata机制,然后指明如何根据该任务过滤任务集。

例如,重新调整@Ian Davis's answer(去读它并立即投票!):

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();

如果您要查找的只是能够为它们命名,则会为名为WithMetadata的{​​{1}}提供速记替换,并使用名称字符串参数替换Named()。可以让你实现@dave thieben的简单性,而不需要将你的调用硬连接到Type name。

编辑:示例,见评论:

.Get<T>()

一些垃圾类

using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace ninjectmess
{
    public class Class1
    {

实际测试

        public interface ITask
        {
        }

        public class Aasdsdaadsdsa : ITask
        {
        }
        public class Bdsadsadasdsadsadsa : ITask
        {
        }
        public class Cddsadasdsadasdas : ITask
        {
        }

答案 1 :(得分:3)

我喜欢Ruben的回答,但它可以像在命令行中使用所需任务的类型名称一样简单:

public static void Main( string[] args )
{
    var kernel = new StandardKernel();
    var tasks = new List<ITask>();
    foreach(var taskName in args)
    {
        tasks.Add( kernel.Get( Type.GetType( taskName ) ) );
    }

    doSomething(tasks);
}