c# - Ninject 与 WhenInjectedInto 扩展方法绑定(bind)

标签 c# dependency-injection ninject ninject-2

我觉得我遗漏了一些明显的东西。我在这里阅读了几个相关问题,并且阅读了 Ninject 的 wiki 上更新的上下文绑定(bind)页面,但遗憾的是它仍然不起作用。

我正在尝试改造使用工厂模式以使用 Ninject 的遗留应用程序。

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

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

我的绑定(bind)是这样设置的...

Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>();

当它运行时,它在 ClassB 的加载方法中失败并出现此错误...

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

如果我尝试以下...

Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>();
Bind<IInterface>().To<ClassB>();

它会无限循环并且永远不会创建 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();
    }

输出是: C类的你好 A类你好

但是我想要: C类的你好 来自 B 类的问候 A类你好

谢谢

最佳答案

没有注入(inject) ClassC。您正在传入内核并直接从中解析 IDoSomething。有很大的不同。

不要将内核作为参数传递——这样做不是依赖注入(inject),而是服务位置(关于区别的好文章:Service Locator is an Anti-Pattern)。

将 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();          
    }     
} 

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

关于c# - Ninject 与 WhenInjectedInto 扩展方法绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7458240/

相关文章:

c# - 拖放至 Windows 窗体问题

c# - Linq 表到 DataTable 转换

c# - 地理 将 LINESTRING 转换为 POLYGON

java - @Resource 与 @Autowired

c# - 使用 IOC 容器作为 MVC5 的依赖解析器会引发 ' cannot create an instance of an interface ' 错误

c# - CultureInfo.InvariantCulture 和 DateTime to String 如何工作

java - Jersey : Injecting of shared object not working with Jetty

javascript - 我如何确定之前是否注入(inject)了 Angular 工厂/服务

asp.net-mvc - Ninject - 跨程序集的依赖注入(inject)

dependency-injection - Ninject Owin 请求范围静默失败