【问题标题】:ASP.NET MVC and Ninject 2.0 Binding QuestionASP.NET MVC 和 Ninject 2.0 绑定问题
【发布时间】:2011-07-23 02:31:06
【问题描述】:

我有一个名为 MyMailSender 的类,它绑定到名为 EmailController 的 asp.net 控制器。

例如

public EmailController(IMailSender sender)
    {
        //MyMailSender
        this.sender = sender;
    }

这个MyMailSender 类也依赖于一个名为MessageSender 的类。

现在我的进程通过执行以下操作在没有注入的情况下工作。

public class MyMailSender : IMailSender
{
    private IMessageSender messageSender;

    public MyMailSender()
    {
        messageSender = new SmtpMessageSender("mail.address.com", 25);
    }
}

如何让这个依赖类使用 Ninject 绑定到 MyMailSender 类?

MyMailSender 初始绑定是通过控制器工厂绑定完成的

public override void Load()
        {
                 Bind<IMailSender>()
                .To<MyMailSender>();            
        }

我尝试绑定到控制器工厂,例如:

  Bind<IMessageSender>()
       .To<SmtpMessageSender>().WithConstructorArgument("mail.address.com", 25);

但我怀疑我不应该在这里绑定这种类型的绑定。我有哪些选择?

我的错误信息是:

Error activating string
No matching bindings are available, and the type is not self-bindable.
Activation path:

  4) Injection of dependency string into parameter hostname of constructor of type SmtpMessageSender

  3) Injection of dependency IMessageSender into parameter messageSender of constructor of type MyMailSender

  2) Injection of dependency IMailSender into parameter sender of constructor of type EmailController

  1) Request for EmailController


Suggestions:
  1) Ensure that you have defined a binding for string.

  2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.

  3) Ensure you have not accidentally created more than one kernel.

  4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.

  5) If you are using automatic module loading, ensure the search path and filters are correct.

【问题讨论】:

    标签: c# asp.net asp.net-mvc ninject ninject.web.mvc


    【解决方案1】:

    这看起来不错。 WithConstructorArgument 用于那些类型的初始化(只要这些参数在应用程序/线程的生命周期内不改变)。

    我会像这样更改MyMailSender 以使用构造函数注入:

    public class MyMailSender : IMailSender
    {
        private IMessageSender _messageSender;
    
        public MyMailSender(IMessageSender messageSender)
        {
            _messageSender = messageSender;
        }
    }
    

    然后在你的onLoad:

    public override void Load()
    {                     
      Bind<IMessageSender>()
           .To<SmtpMessageSender>()
           .WithConstructorArgument("hostname", "mail.address.com")
           .WithConstructorArgument("port", 25);
      Bind<IMailSender>()
           .To<MyMailSender>();     
    }
    

    作为一般提示,只要您在课堂上看到 new 的东西,就把它当作一种气味。当使用任何 DI 框架时,new 应该很少出现在您的代码中(例如在工厂等中)

    另一个建议是从一些配置/设置文件中加载地址和端口,而不是硬编码。

    【讨论】:

    • 我尝试 MyMailSender 使用来自乞求的构造函数注入并得到一个错误。--->错误激活字符串没有可用的匹配绑定,并且类型不可自绑定。激活路径:4)将依赖字符串注入到SmtpMessageSender类型的构造函数的参数hostname中
    • 抱歉,请参阅我的更新。使用WithConstructorArgument() 时需要指定参数名称和值。我假设了参数名称,但你明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多