2

Je viens de commencer à utiliser l'injection de dépendance pour la première fois et j'utilise Ninject 2.0 comme conteneur IoC dans un site Web ASP.NET MVC 2 et j'obtiens une erreur d'activation que je ne suis pas sûr de savoir comment réagir. Je suis sûr que c'est simple alors j'espère que quelqu'un peut me diriger dans la bonne direction sans trop y penser.ASP.NET MVC - Erreur d'activation de Ninject 2.0

J'ai une propriété sur ma classe BaseController qui prend un IWebsiteSettings et est marquée avec l'attribut [Inject]. Dans mon StandardKernel je charge un module avec le code suivant:

public class WebModule : Module 
{ 
    public override void Load() 
    { 

     Bind<IWebsiteSettings>() 
      .ToProvider(new WebsiteSettingsProvider(WebConfigurationManager.AppSettings)) 
      .InSingletonScope(); 

    } 
} 

public class WebsiteSettingsProvider : Provider<WebsiteSettings> 
{ 
    private const string WebsiteNameKey = "Website.Name"; 
    private const string ContactFormEmailSubjectKey = "ContactForm.EmailSubject"; 
    private const string ProductImageDirectoryKey = "Products.ImageDirectory"; 
    private const string UploadTempDirectoryKey = "Uploads.TempDirectory"; 

    protected NameValueCollection Settings { get; set; } 

    public WebsiteSettingsProvider(NameValueCollection settings) 
    { 
     Settings = settings; 
    } 

    protected override WebsiteSettings CreateInstance(IContext context) 
    { 
     return new WebsiteSettings 
        { 
         WebsiteName = Settings[WebsiteNameKey] ?? string.Empty, 
         ContactFormEmailSubject = Settings[ContactFormEmailSubjectKey] ?? string.Empty, 
         ProductImageDirectory = Settings[ProductImageDirectoryKey] ?? string.Empty, 
         UploadsTemporaryDirectory = Settings[UploadTempDirectoryKey] ?? string.Empty 
        }; 
    } 
} 

Ceci est assez straightforward- Je suis en train de charger des données à partir du fichier web.config et le stocker dans un objet singleton pour une utilisation sur mes contrôleurs . L'appel à Bind semble fonctionner exactement comme il se doit et la propriété Settings de mon fournisseur est correctement initialisée avec la collection AppSettings dans le fichier de configuration. Pourtant, lorsque l'application charge la première fois:

 
Server Error in '/' Application. 
Error activating SByte* using implicit self-binding of SByte* 
No constructor was available to create an instance of the implementation type. 

Activation path: 
4) Injection of dependency SByte* into parameter value of constructor of type string 
3) Injection of dependency string into property WebsiteName of type WebsiteSettings 
2) Injection of dependency IWebsiteSettings into property WebsiteSettings of type HomeController 
1) Request for HomeController 

Suggestions: 
1) Ensure that the implementation type has a public constructor. 
2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead. 

Fait intéressant, si j'actualisez la page Je ne reçois pas l'exception et un appel à Kernel.Get() retourne l'objet correct.

Un conseil?

Répondre

2

(Nous en avons parlé sur IRC, mais je suis en train ici au cas où quelqu'un court d'autre dans ce problème aussi bien.)

WebsiteSettings a [Inject] attributs sur ses propriétés, afin Ninject tente de résoudre un liaison de System.String pour injecter une valeur dans les propriétés. Comme vous utilisez un fournisseur personnalisé pour activer les instances WebsiteSettings, vous n'avez pas besoin des attributs [Inject] dans ses propriétés.

+0

quel canal irc? –

0

Le code incriminé était en fait dans les WebsiteSettings de classe où je faisais ceci:

public class WebsiteSettings : IWebsiteSettings 
{ 
    [Ninject.Inject] 
    public string WebsiteName 
    { 
     get; set; 
    } 

    [Ninject.Inject] 
    public string UploadsTemporaryDirectory 
    { 
     get; set; 
    } 

    [Ninject.Inject] 
    public string ContactFormEmailSubject 
    { 
     get; set; 
    } 

    [Ninject.Inject] 
    public string ProductImageDirectory 
    { 
     get; set; 
    } 
} 

En plaçant l'Injecter attribut sur mes propriétés que j'était à l'origine Ninject d'essayer d'attribuer des valeurs que je ne Bound. Comme j'utilise un fournisseur pour charger mon type, je n'ai pas besoin d'inclure l'attribut Inject.

Questions connexes