[英]Is it possible to setup Ninject bindings to create multiple instances of same class?
我們有一個(奇怪的?)要求來創建X個相同類的實例,並且我們將Ninject用於IoC。 顯然,我們可以通過多次請求相同類型的對象來手動完成此操作:
for (var i = 0; i <= 10; i++)
{
var obj = _kernel.GetService(typeof(MyType));
...
}
這可以按預期工作,但是現在我們必須訪問代碼中的內核才能做到這一點,而且“很臭”。 我更喜歡在綁定中處理它,就像InRequestScope一樣。
為了給所有這些增加一點復雜性,我們還指定了它自己的對象上的實例數,因此上面的代碼實際上更接近於此:var obj =(MyType)_kernel.GetService(typeof(MyType));
for (var i = 0; i <= obj.NumberOfInstances; i++)
{
var obj = _kernel.GetService(typeof(MyType));
...
}
最后一件真正使它變得混亂的事情; 我們使用Ninject約定將實現綁定到基礎:var assembly = AppDomain.CurrentDomain.GetAssemblies();
this.Bind(x => x
.From(assemblies)
.SelectAllClasses()
.InheritedFrom<BaseMyType>()
.BindAllBaseClasses());
我希望能夠使用的實現是這樣的:
this.Bind(x => x
.From(assemblies)
.SelectAllClasses()
.InheritedFrom<BaseMyType>()
.BindAllBaseClasses()
.Configure(syntax => syntax.InMultipleScope()));
但這可能或不可能或不是一個好主意...
有人做過這樣的事情嗎? 也許您可以看到一種不同的方式?
需求上的詳細信息:我們在單個Azure Worker角色中創建多個線程,這將有利於運行同一代碼的多個副本。
您要的,所以我要給您這個非常臭的丑陋代碼;-)
using System;
using System.Collections.Generic;
using FluentAssertions;
using Ninject;
using Ninject.Extensions.Conventions;
using Ninject.Extensions.Conventions.BindingGenerators;
using Ninject.Syntax;
using Xunit;
public class MultiBaseBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
for (int i = 0; i < 10; i++)
{
yield return bindingRoot.Bind(type.BaseType).To(type);
}
}
}
public abstract class Foo
{
}
public class SomeFoo : Foo
{
}
public class SomeFooUser
{
public IEnumerable<Foo> Foos { get; set; }
public SomeFooUser(IEnumerable<Foo> foos)
{
this.Foos = foos;
}
}
public class Demo
{
[Fact]
public void FactMethodName()
{
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<Foo>()
.BindWith<MultiBaseBindingGenerator>());
kernel.Get<SomeFooUser>().Foos.Should().HaveCount(10);
}
}
每次插入IEnumerable<Foo>
時,這將創建10個Foo實例。 您可以通過將屬性放在類型上並讀取IBindingGenerator
來使實例計數可配置。 但是,只能在創建綁定時或之前讀取配置。
還有其他幾種可能性可以達到相同的目標。 我建議僅創建一個綁定-就像您現在所做的那樣。 創建一個工廠IEnumerable CreateMultipleAsConfigured(),該工廠創建所需數量的實例。
另一種可能性是創建自己的集合類型:
public class MultipleAsConfigured<T> : Collection<T> { }
並使用提供程序將其綁定:
IBindingRoot.Bind(typeof(MultipleAsConfigured<>).ToProvider(typeof(MultipleAsConfiguredProvider));
並讓提供程序讀取配置,實例化所需數量的對象(使用IContext.Get()),創建MultipleAsConfigured並添加項...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.