ninject - 运行时绑定(bind) : A simple task runner with ninject?

标签 ninject

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

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

public interface ITask
{
   void Run();
}

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

我希望能够在运行时指定要运行哪些任务,从而指定要激活的 ITask 实现。

我想我可以将具体类型放入我的 app.config 中,然后在运行时我可以让 ninject 从中构建一个 ITask 数组。如果失败,我可以指定要在命令行上运行的任务。

对我来说,这听起来像是 ninject 的一个相当简单的例子,但我一直无法找到如何让 ninject 从配置或字符串绑定(bind)。

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

最佳答案

extensions用于处理 xml 配置等事务的 ninject。

不过,我会小心地将配置中的编程位与 Spring XML 配置混合起来 - 无需仅仅为了允许人们在 .config 文件中配置内容而转向 XML 配置。我建议阅读一个 XML 配置节加载器,它在一个类中进行序列化,从而在更高级别上表达它。

您可以使用metadata绑定(bind)注册机制,然后指示如何基于该机制过滤任务集。

例如,重新利用@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 可以用简写替代。叫Named().Get<T>() 的过载带有名称字符串参数,这将使您实现 @dave thieben 的简单性,而无需将调用硬连线到类型名称。

编辑:示例,请参阅评论:

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
        {
        }

实际测试

        [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 );
        }
    }
}

关于ninject - 运行时绑定(bind) : A simple task runner with ninject?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4896390/

相关文章:

jquery - 是否有一种 native 方法可以创建客户端模型以发布到我的 Controller 而无需手动滚动它们?

asp.net-mvc-3 - MVC 3 依赖注入(inject)与 Ninject 2.2 + 全局 Action 过滤器

c# - 在单个 Web API 请求中使用 MySQL 和 SQL Server 上下文

ninject - 如何将 Ninject 集成到 ASP.NET Core 2.0 Web 应用程序中?

c# - 使用 Ninject 进行类型激活

asp.net-mvc - 如何告诉 Ninject 绑定(bind)到它没有引用的实现

nhibernate - 正确使用NHibernate工作单元模式和Ninject

c# - 如何在 WebApi OwinHost Startup 中使用 Ninject bootstrapper?

.net - 使用 ToMethod 时配置 Ninject 以解决 null

c# - ASP.NET MVC 4 + Ninject MVC 3 = 没有为此对象定义无参数构造函数