2011-07-23 7 views
2

J'ai une classe appelée MyMailSender qui se lie au contrôleur asp.net appelé EmailController.ASP.NET MVC et Ninject 2.0 Binding Question

E.g.

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

Cette MyMailSender classe est également dépendante d'une classe appelée MessageSender.

À l'heure actuelle, mon processus fonctionne sans injection en procédant comme suit.

public class MyMailSender : IMailSender 
{ 
    private IMessageSender messageSender; 

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

Comment puis-je obtenir cette classe dépendante de se lier à la classe MyMailSender en utilisant Ninject?

liaison initiale MyMailSender se fait via l'usine de contrôleur de liaison

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

J'ai essayé de se lier à l'usine de contrôleur comme:

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

mais je pense que je ne devrais pas lier ici pour ce type de reliure . Quelles sont mes options?

Mon message d'erreur est:

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. 

Répondre

4

Cela ressemble bien. WithConstructorArgument est destiné à ces types d'initialisations (tant que ces arguments ne changent pas pour la durée de vie de aaplication/thread).

Je changerais MyMailSender comme celui-ci à utiliser l'injection de constructeur:

public class MyMailSender : IMailSender 
{ 
    private IMessageSender _messageSender; 

    public MyMailSender(IMessageSender messageSender) 
    { 
     _messageSender = messageSender; 
    } 
} 

Et puis dans votre onLoad:

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

En tant que conseil général, chaque fois que vous voyez un new somthing dans vos classes, Prends ça comme une odeur. new devrait être trouvé rarement dans votre code (comme dans les usines etc.) lors de l'utilisation de toute structure DI

Une autre suggestion consiste à charger l'adresse et le port à partir de certains fichiers de configuration/configuration plutôt que de coder en dur.

+0

J'ai essayé MyMailSender d'utiliser l'injection de constructeur de la demande et ai obtenu une erreur .---> Erreur d'activation de la chaîne Aucune liaison correspondante n'est disponible, et le type n'est pas auto-lier. Chemin d'activation: 4) Injection de chaîne de dépendance dans le paramètre nom d'hôte du constructeur de type SmtpMessageSender – Keith

+0

Désolé, voir ma mise à jour. Vous devez spécifier le nom et la valeur du paramètre lors de l'utilisation de 'WithConstructorArgument()'. J'ai assumé les noms de param mais vous avez l'idée. – Mrchief

+0

Merci! C'est ce que j'ai fait! – Keith