沒有出來這樣的情景內置支持。 雖然有很多方法可以實現你想要的。
因此,讓我們開始
public class Runner
{
public Runner(IService1 service1, IService2 service2, IConfig config, IControl control)
{
}
public void Run()
{
}
}
解決方案1 : 我們將使用一個.ToFactory()
結合創建亞軍 - 所具有的依賴注入。
public interface IRunnerFactory
{
// all parameters are passed to the constructor of Runner
// parameters are matched by name, so make sure they match! ctor(IConfig myconfig) won't work, it must be ctor(IConfig config).
// but of course you can add more parameters to the ctor and have them injected: ctor(IService1 foo, IControl bar, IConfig config, IService2 foo2)
Runner Create(IConfig config);
}
public class AllRunner
{
private readonly IList<IConfig> runnerConfigurations;
private readonly IRunnerFactory runnerFactory;
public AllRunner(IList<IConfig> runnerConfigurations, IRunnerFactory runnerFactory)
{
this.runnerConfigurations = runnerConfigurations;
this.runnerFactory = runnerFactory;
}
public void RunAll()
{
Task[] runners = this.runnerConfigurations
.Select(this.runnerFactory.Create)
.Select(runner => Task.Run((Action) runner.Run))
.ToArray();
Task.WaitAll(runners);
}
}
// you could also use .InNamedScope() or maybe InParentScope() or InCallScope() -- see the NamedScope extension!
kernel.Bind<IControl>().To<Control>().InSingletonScope();
// implementation is auto generated.
kernel.Bind<IRunnerFactory>().ToFactory();
kernel.Bind<IConfig>().To<Config1>();
kernel.Bind<IConfig>().To<Config2>();
kernel.Bind<IConfig>().To<Config3>();
注:
解決方案2
我們將延長解決方案1和使用供應商/ .ToProvider()
結合,所以我們可以注入IReadOnlyCollection<Runner>
。
public class RunnersProvider : Provider<IReadOnlyCollection<Runner>>
{
private readonly IList<IConfig> runnerConfigurations;
private readonly IRunnerFactory runnerFactory;
public RunnersProvider(IList<IConfig> runnerConfigurations, IRunnerFactory runnerFactory)
{
this.runnerConfigurations = runnerConfigurations;
this.runnerFactory = runnerFactory;
}
protected override IReadOnlyCollection<Runner> CreateInstance(IContext context)
{
return this.runnerConfigurations
.Select(this.runnerFactory.Create)
.ToArray();
}
}
kernel.Bind<IReadOnlyCollection<Runner>>().ToProvider<RunnersProvider>();
然後你可以做
IResolutionRoot.Get<IReadOnlyCollection<Runner>>()
,或者也注入IReadOnlyCollection<Runner>
成男星 - 但不是IEnumerable<Runner>
或任何其他類型的,因爲你明確地結合IReadOnlyCollection<Runner>
,而不是利用ninject的多結合/多次注射功能。
你也需要注意的是kernel.Bind<IEnumerable<Foo>>()
(同樣適用於IList<>
,ICollection<>
和foo[]
- 所有類型ninject支持自動多注射液)是脆。您可以執行kernel.Get<IEnumerable<Foo>>()
,但不能注入相同類型,因爲如果將它用於ctor-injection,ninject會嘗試找到與Foo
匹配的綁定,而不是IEnumerable<Foo>
(多注入支持)。
這看起來很有希望,但我需要處理一下這一點^ _^ 在相關的不是,IConfig對象是使用foreach從App.config轉換字符串添加的; 的foreach(IConfig下在Config.Select(JSON)) 綁定().ToConstant(C); 有沒有更好的辦法做到這一點呢? 以上配置屬性只是Properties.Settings.Default的包裝...由 –
你應該考慮不是在所有綁定'IConfig'的方式。代替綁定'IConfigReader'與方法'的IEnumerable ReadConfig()'。 –
BatteryBackupUnit
當我嘗試解決方案與IConfigReader方法結合使用後,當我調用configs.Select(factory.Create).ToList() –