c# - BindBase 只绑定(bind)直系祖先

标签 c# ninject ninject-extensions

我的代码中也有类似的情况,我有一个从两个祖先抽象类派生的类,如下所示:

BaseAbstractClassExample <|-- AbstractClassExample <|-- ConcreteClassExample

我这样做是为了扩展框架中定义的抽象类。虽然我知道还有其他设计模式可能更适合我的情况,但我很好奇为什么这种基于约定的绑定(bind)不起作用。

using Ninject.Extensions.Conventions; 

public abstract class BaseAbstractClassExample
{
    public abstract int Number { get; set; }
}

public abstract class AbstractClassExample : BaseAbstractClassExample
{
    public abstract bool Flag { get; set; }
}

public class ConcreteClassExample : AbstractClassExample
{
    public override int Number { get; set; }
    public override bool Flag { get; set; }
}

[TestMethod]
public void Concrete_classes_are_bound_to_grandfathers()
{
    kernel.Bind(x => x.FromThisAssembly()
                        .SelectAllClasses().InheritedFrom<BaseAbstractClassExample>()                            
                        .BindBase());

    AssertCanResolveBindingToType<ConcreteClassExample, ConcreteClassExample>(); // pass
    AssertCanResolveBindingToType<AbstractClassExample, ConcreteClassExample>(); // pass
    AssertCanResolveBindingToType<BaseAbstractClassExample, ConcreteClassExample>(); // fail
}

这是我为测试绑定(bind)而编写的断言方法,这与我的问题无关。

private static void AssertCanResolveBindingToType<TRequestedType, TExpectedType>(params IParameter[] constructorParameters)
    {
        if (!typeof(TRequestedType).IsAssignableFrom(typeof(TExpectedType)))
            Assert.Fail("{0} is not assignable from {1}, this binding wouldn't work anyway", typeof(TRequestedType), typeof(TExpectedType));

        IEnumerable<TRequestedType> result = kernel.GetAll<TRequestedType>(constructorParameters);
        var requestedTypes = result as TRequestedType[] ?? result.ToArray();
        Assert.IsTrue(requestedTypes.Any(), "There are no bindings for {0} at all", typeof (TRequestedType));
        Assert.IsTrue(requestedTypes.OfType<TExpectedType>().Any(),
                      "There are no bindings for {0} of the expected type {1}, bound types are: {2}", 
                      typeof (TRequestedType), typeof (TExpectedType),
                      string.Join(", ", requestedTypes.Select(x => x.GetType().ToString()).Distinct()));
    }

当我尝试上面的单元测试时,它断言我的自定义消息“根本没有 BaseAbstractClassExample 的绑定(bind)”,这表明与 AbstractClassExample 的绑定(bind)按预期工作,但不是一到BaseAbstractClassExample

编辑:我编写了一个提供此功能的方法BindAllBaseClasses()。我提交了一个拉取请求并获得了批准,因此此功能现在可以在 Ninject extensions conventions 中使用。图书馆。

最佳答案

正如 Daniel 所解释的,SelectAllClasses() 选择所有非抽象类。选择抽象类是没有意义的,因为不可能创建它们的实例。

因此,在您的情况下,它选择ConcreteClassExample

然后BindBase() 告诉应添加基类到所选类的绑定(bind)。在你的情况下是:

Bind<AbstractClassExample>().To<ConcreteClassExample>();

现在您可以解析 AbstractClassExample 因为有一个绑定(bind),而 ConcreteClassExample 因为它是 self 绑定(bind),即使没有配置,Ninject 也会创建一个隐式 self 绑定(bind)。

您无法解析 BaseAbstractClassExample,因为它既没有绑定(bind),也不能自绑定(bind),因为它是抽象的。

关于c# - BindBase 只绑定(bind)直系祖先,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18091906/

相关文章:

c# - 如何在 C# 注释中添加 xaml 代码?

c# - Entity Framework 模型不显示具有复合键的表

c# - 将具体实例注入(inject) Ninject 解析器

c# - 处理基类异常

c# - 停止 HSTS HTTPS 执行

.net - Ninject InSingletonScope() View 模型在绑定(bind)时未分配给 View

asp.net-mvc - 如何使用 Ninject 将 ModelState 作为参数注入(inject)?

asp.net-mvc-3 - 具有 ninject 的插件架构 - 将类和 Controller 实例从插件程序集加载到主 MVC 项目

c# - Ninject 工厂 + InCallScope + ContextPreservation

c# - Ninject.Extensions.Logging.Log4Net 为类/方法名称生成不正确的输出