我有以下接口和具体实现:
end
你可以看到Bar在类构造函数中依赖于Foo。
这些是我的约束力:
interface IFoo {
string Name { get ;}
}
class Foo :IFoo{
public string Name { get; set; }
}
interface IBar {
string Name { get; }
}
class Bar : IBar {
public string Name { get;set;}
public Bar(Foo foo) {
}
}
当我使用kernel.Bind<IFoo>().ToConstant(new Foo() { Name="Foo"; });
kernel.Bind<IBar>().To<Bar>();
并请求Bar时,没有错误,但Foo依赖是我最初绑定的kernel.Get
的不同实例。我希望看到Foo的名字是&#34; Foo&#34;当我检查Bar构造函数内部的Foo实例时,我看到Foo {Name = null}。
当我绑定到具体的Foo时,一切都按预期工作:
Foo
是否有方便的方法将Foo的特定实例绑定到所有可用接口和具体类型?
例如:
var foo = new Foo() { Name="Foo" };
kernel.Bind<IFoo>().ToConstant(foo);
kernel.Bind<Foo>().ToConstant(foo);
kernel.Bind<IBar>().To<Bar>();
var bar= kernel.Get<Bar>(); // works! foo has name "Foo"
我有一个通用框架。框架之外是客户定义的Foo和Bar。我希望客户能够灵活地在Bar构造函数中指定IFoo或Foo。如果构造函数被定义为Bar(IFoo),则客户端可能会将其转换为Foo。
答案 0 :(得分:1)
ninject没有提供此类功能。 ninject提供的是绑定到多种类型,例如:
Bind<IFoo,Foo>().To<Foo>().InSingletonScope();
确保无论请求IFoo
和Foo
的哪种组合,您始终都会获得相同的Foo
个实例。
然后,Ninject.Extensions.Conventions可以查找类型(就像程序集的所有类一样)并将它们绑定到它们的所有接口,它们的所有基类型,......但只是两个或两个,而不是两个。你可以用它来达到你想要的效果,但是你需要一些代码,而且它会有点笨拙。
因此,在我看来,最好只是自己动手:
using Ninject.Infrastructure.Language;
public static void RegisterConstantAsAllTypes(IBindingRoot bindingRoot, object instance)
{
Type t = instance.GetType();
IEnumerable<Type> typesToBind = t.GetAllBaseTypes()
.Concat(t.GetInterfaces())
.Except(new[] { typeof(object) });
bindingRoot
.Bind(typesToBind.ToArray())
.ToConstant(instance);
}
鉴于您的示例,以下测试通过:
[Fact]
public void FactMethodName()
{
var kernel = new StandardKernel();
var foo = new Foo();
RegisterConstantAsAllTypes(kernel, foo);
kernel.Get<IFoo>().Should().Be(foo);
kernel.Get<Foo>().Should().Be(foo);
kernel.Get<AbstractFoo>().Should().Be(foo);
}