是否有一种简单的方法可以将所有可用类型绑定到具体实例

时间:2016-01-06 08:08:50

标签: c# ninject

我有以下接口和具体实现:

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。

1 个答案:

答案 0 :(得分:1)

ninject没有提供此类功能。 ninject提供的是绑定到多种类型,例如:

Bind<IFoo,Foo>().To<Foo>().InSingletonScope();

确保无论请求IFooFoo的哪种组合,您始终都会获得相同的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);
}