ASP.NET MVC activation error - Ninject 2.0

I just started working with dependency injection for the first time and I am using like Ninject 2.0 as my IoC container in ASP.NET MVC 2 website and I find an activation error that I am not sure how to react to, I am sure that it's just like that, hopefully someone can point me in the right direction without a second thought.

I have a property on my BaseController class that accepts IWebsiteSettings and is marked with the [Inject] attribute. In my Standard kernel, I load a module with the following code:

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
                   };
    }
}

      

It's pretty simple: I'm trying to load some data from a web.config file and store it in a single object for use across my controllers. The Bind function call works exactly as it should, and the Settings property in my provider is correctly initialized by the AppSettings collection in the config file. However, when the app is loaded for the first time:

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.

Interestingly, if I refresh the page, I don't get an exception and the Kernel.Get () call returns the correct object.

Any advice?

+2


source to share


2 answers


(We talked about this on IRC, but I'll post it here in case anyone else has this problem.)



WebsiteSettings

has attributes [Inject]

on its properties, so Ninject tries to resolve the binding from System.String

in order to insert the value into the properties. Since you are using a custom provider to activate instances WebsiteSettings

, you do not need attributes [Inject]

for its properties.

+2


source


The offending code was actually in the WebsiteSettings class where I was doing this:

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;
    }
}

      



By putting the Inject attribute on my properties, I made Ninject try to assign values ​​that I had never bound. Since I am using Provider to load my type, I do not need to include the Inject attribute.

0


source







All Articles