2

我有一个名为 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);
    }
}

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

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.
4

1 回答 1

4

这看起来不错。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在课堂上看到某样东西时,就把它当作一种气味。new使用任何 DI 框架时,应该很少在您的代码中找到(例如在工厂等中)

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

于 2011-07-23T03:44:27.950 回答