C# 使用WhenInjectedTo扩展方法的Ninject绑定

C# 使用WhenInjectedTo扩展方法的Ninject绑定,c#,dependency-injection,ninject,ninject-2,C#,Dependency Injection,Ninject,Ninject 2,我觉得我错过了一些明显的东西。我已经在这里读了几个相关的问题,并且在Ninject的wiki上读了更新的上下文绑定页面,但可惜它仍然不起作用 我正试图改造一个使用工厂模式来使用Ninject的遗留应用程序 我有一个接口(IInterface),由两个类(ClassB和ClassC)实现。界面有一个加载方法。在ClassB的load方法中,它实例化ClassC,然后执行它的load方法 基本上,程序流是ClassA创建ClassB并执行load方法。在load方法中,ClassB创建完成一些工作的

我觉得我错过了一些明显的东西。我已经在这里读了几个相关的问题,并且在Ninject的wiki上读了更新的上下文绑定页面,但可惜它仍然不起作用

我正试图改造一个使用工厂模式来使用Ninject的遗留应用程序

我有一个接口(IInterface),由两个类(ClassB和ClassC)实现。界面有一个加载方法。在ClassB的load方法中,它实例化ClassC,然后执行它的load方法

基本上,程序流是ClassA创建ClassB并执行load方法。在load方法中,ClassB创建完成一些工作的ClassC

我的绑定设置为

Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>();
Bind().To().whenInjectedTo();
当对象为()时,将()绑定到();
当它运行时,它在ClassB的load方法中失败,并出现以下错误

激活IInterface时出错没有匹配的绑定可用,并且类型不可自绑定

如果我尝试以下方法

Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>();
Bind().To().whenInjectedTo();
绑定()到();
它执行一个无止境的循环,从不创建ClassC

编辑 我已经把它简化为一个单元测试,它通过了,但没有给出我想要的结果

[TestClass]
public class NinjectTestFixture
{
    private interface IDoSomething
    {
        void SaySomething();
    }

    private class ClassA : IDoSomething
    {
        public void SaySomething()
        {
            Console.WriteLine("Hello from Class A");
        }
    }

    private class ClassB : IDoSomething
    {
        private IKernel _Kernel;

        public ClassB(IKernel kernel)
        {
            _Kernel = kernel;
        }

        public void SaySomething()
        {
            Console.WriteLine("Hello from Class B");

            var x = _Kernel.Get<IDoSomething>();

            x.SaySomething();
        }
    }

    private class ClassC
    {
        private IKernel _Kernel;

        public ClassC(IKernel kernel)
        {
            _Kernel = kernel;
        }

        public void SaySomething()
         {
             Console.WriteLine("Hello from Class C");

             var x = _Kernel.Get<IDoSomething>();

             x.SaySomething();
         }
    }

    [TestMethod]
    public void TestMethod1()
    {
        var kernel = new StandardKernel();

        kernel.Bind<IDoSomething>().To<ClassA>();
        kernel.Bind<IDoSomething>().To<ClassB>().WhenInjectedInto<ClassC>();
        kernel.Bind<ClassC>().ToSelf();

        var x = kernel.Get<ClassC>();

        x.SaySomething();
    }
[TestClass]
公共类测试夹具
{
私有接口
{
虚空说某事;
}
私人班级A:我有什么事吗
{
公开的,公开的
{
Console.WriteLine(“来自A类的你好”);
}
}
二等兵B类:我是什么
{
私有IKernel_内核;
公共类B(IKernel内核)
{
_内核=内核;
}
公开的,公开的
{
Console.WriteLine(“来自B类的你好”);
var x=_Kernel.Get();
x、 说点什么;
}
}
C类私人舱
{
私有IKernel_内核;
公共类C(IKernel内核)
{
_内核=内核;
}
公开的,公开的
{
Console.WriteLine(“来自C类的你好”);
var x=_Kernel.Get();
x、 说点什么;
}
}
[测试方法]
公共void TestMethod1()
{
var kernel=新的标准内核();
kernel.Bind().To();
kernel.Bind().To().WhenInjectedInto();
kernel.Bind().ToSelf();
var x=kernel.Get();
x、 说点什么;
}
输出为: C班同学你好 A班同学你好

但我想: C班同学你好 B班的同学你好 A班同学你好

谢谢

您不是注入到ClassC中。您正在传入内核并直接从中解析IDO。这有很大的区别

不要将内核作为参数传递——这样做不是依赖注入,而是服务位置(关于差异的好文章:)

将ClassC更改为:

private class ClassC     
{         
    private IDoSomething _doSomething;          
    public ClassC(IDoSomething doSomething)
    {             
        _doSomething = doSomething;         
    }          

    public void SaySomething()          
    {              
        Console.WriteLine("Hello from Class C");               
        //var x = _Kernel.Get<IDoSomething>();               
        _doSomething.SaySomething();          
    }     
} 
私有类c
{         
私密的东西;
公共C类(IDOMETHING)
{             
_doSomething=doSomething;
}          
公开的,公开的
{              
Console.WriteLine(“来自C类的你好”);
//var x=_Kernel.Get();
_说点什么;
}     
} 

您还应该对ClassA和ClassB进行相同的更改(传递您想要解析的类型/接口,而不是内核).

我理解你的意思,但在方法中,我需要实例化一个对象来做一些工作。在同一个类中,还有其他方法实例化方法来做更多工作。如果我按照你的建议做,我的构造函数中会有大约20个参数。代码最初是6年前编写的,所以我正在尝试逐步用DI对其进行改造。我绞尽脑汁研究如何做到这一点,传递内核是最简单、最有意义的解决方案。我查看了一个服务位置,但考虑到当前的代码基础,这没有意义。你的回答是正确的。当我做出你建议的更改时,我得到了我预期的结果。我明白你的意思——我也是ave重构了系统,我不得不使用一些奇怪/难看的临时步骤来引入DI。