有没有一种简单的方法可以将所有可用类型绑定到一个具体实例
Is there an easy way to bind all available types to a concrete instance
我有以下接口和具体实现:
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) {
}
}
在class构造函数中可以看到Bar对Foo有依赖关系
这些是我的绑定:
kernel.Bind<IFoo>().ToConstant(new Foo() { Name="Foo"; });
kernel.Bind<IBar>().To<Bar>();
当我使用 kernel.Get
并请求 Bar 时,没有错误,但是 Foo 依赖项是我最初绑定的 Foo
的不同实例。当我检查 Bar 构造函数中的 Foo 实例时,我希望看到名称为 "Foo" 的 Foo,但我看到的却是 Foo { Name = null }.
当我绑定到具体的 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 的特定实例绑定到所有可用接口和具体类型?
例如:
class ConcreteFoo : AbstractFoo, IFoo {
...
}
var foo = new Foo();
kernel.Bind<IFoo>().ToConstant(foo);
kernel.Bind<AbstractFoo>().ToConstant(foo);
kernel.Bind<ConcreteFoo>().ToConstant(foo);
我有一个通用框架。框架之外是客户定义的 Foo 和 Bar。我希望客户能够灵活地在 Bar 构造函数中指定 IFoo 或 Foo 。如果构造函数被定义为 Bar(IFoo),客户端可能无论如何都会将其转换为 Foo。
ninject 没有提供此类功能。 ninject 提供的是绑定到多种类型,例如:
Bind<IFoo,Foo>().To<Foo>().InSingletonScope();
确保无论请求 IFoo
和 Foo
的什么组合,您总是得到相同的 Foo
实例。
然后,Ninject.Extensions.Conventions 可以查找类型(就像一个程序集的所有 类)并将它们绑定到它们所有的接口、它们所有的基类型,...但只能是 or , 不是都。你可以用它来实现你想要的,但它也需要你的代码,..而且有点尴尬。
所以,在我看来,最好自己动手:
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);
}
我有以下接口和具体实现:
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) {
}
}
在class构造函数中可以看到Bar对Foo有依赖关系
这些是我的绑定:
kernel.Bind<IFoo>().ToConstant(new Foo() { Name="Foo"; });
kernel.Bind<IBar>().To<Bar>();
当我使用 kernel.Get
并请求 Bar 时,没有错误,但是 Foo 依赖项是我最初绑定的 Foo
的不同实例。当我检查 Bar 构造函数中的 Foo 实例时,我希望看到名称为 "Foo" 的 Foo,但我看到的却是 Foo { Name = null }.
当我绑定到具体的 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 的特定实例绑定到所有可用接口和具体类型?
例如:
class ConcreteFoo : AbstractFoo, IFoo {
...
}
var foo = new Foo();
kernel.Bind<IFoo>().ToConstant(foo);
kernel.Bind<AbstractFoo>().ToConstant(foo);
kernel.Bind<ConcreteFoo>().ToConstant(foo);
我有一个通用框架。框架之外是客户定义的 Foo 和 Bar。我希望客户能够灵活地在 Bar 构造函数中指定 IFoo 或 Foo 。如果构造函数被定义为 Bar(IFoo),客户端可能无论如何都会将其转换为 Foo。
ninject 没有提供此类功能。 ninject 提供的是绑定到多种类型,例如:
Bind<IFoo,Foo>().To<Foo>().InSingletonScope();
确保无论请求 IFoo
和 Foo
的什么组合,您总是得到相同的 Foo
实例。
然后,Ninject.Extensions.Conventions 可以查找类型(就像一个程序集的所有 类)并将它们绑定到它们所有的接口、它们所有的基类型,...但只能是 or , 不是都。你可以用它来实现你想要的,但它也需要你的代码,..而且有点尴尬。
所以,在我看来,最好自己动手:
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);
}