我正在编写一个简单的任务运行器应用程序.
我有一堆实现ITask接口的类:
public interface ITask
{
void Run();
}
Run Code Online (Sandbox Code Playgroud)
我正在编写一个简单的控制台应用程序来创建ITasks实例,然后在每个应用程序上调用Run().任务实现使用构造函数注入,所以我想使用ninject.
我希望能够在运行时指定要运行哪些任务以及因此要激活哪些ITask实现.
我想我可以将具体类型放入我的app.config然后在运行时我可以获得ninject从中构建一个ITask数组.如果做不到这一点,我可以指定我想在命令行上运行的任务.
对我来说,这听起来像ninject的一个相当直接的案例,但我一直无法找到如何从配置或字符串绑定ninject.
任何人都能指出我正确的方向吗?
有ninject的扩展可以处理xml配置之类的东西.
我要小心将Spring和Spring配置中的编程位混合起来 - 没有必要转移到XML配置只是为了让人们在.config文件中配置东西.我建议阅读一个XML配置节加载器,它在一个表示序列化的类中表示更高级别.
您将在Binding注册上使用元数据机制,然后指示如何基于此过滤任务集.
例如,重新利用@Ian Davis的答案(去读它并立即投票!):
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();
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找的只是能够命名它们,那么可以使用名称字符串参数替换WithMetadata被调用Named()和重载.Get<T>(),这样可以实现@dave thieben的简单性,而无需将您的调用硬连接到类型名称.
编辑:示例,请参阅注释:
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace ninjectmess
{
public class Class1
{
Run Code Online (Sandbox Code Playgroud)
一些垃圾类
public interface ITask
{
}
public class Aasdsdaadsdsa : ITask
{
}
public class Bdsadsadasdsadsadsa : ITask
{
}
public class Cddsadasdsadasdas : ITask
{
}
Run Code Online (Sandbox Code Playgroud)
实际测试
[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 );
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1383 次 |
| 最近记录: |