ASP.NET MVC - ошибка активации Ninject 2.0 - PullRequest
2 голосов
/ 27 августа 2009

Я только начал работать с внедрением зависимостей в первый раз, и я использую Ninject 2.0 в качестве своего контейнера IoC на веб-сайте ASP.NET MVC 2, и у меня возникает ошибка активации, на которую я не уверен, как реагировать на , Я уверен, что это просто, так что, надеюсь, кто-то может направить меня в правильном направлении, не слишком задумываясь.

У меня есть свойство в моем классе BaseController, которое принимает IWebsiteSettings и помечено атрибутом [Inject]. В моем StandardKernel я загружаю модуль со следующим кодом:

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

Это довольно просто - я пытаюсь загрузить некоторые данные из файла web.config и сохранить их в одноэлементном объекте для использования на моих контроллерах. Кажется, что вызов Bind работает точно так, как должен, и свойство Settings в моем провайдере правильно инициализировано с коллекцией AppSettings в файле конфигурации. Тем не менее, когда приложение загружается в первый раз:

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.

Интересно, что если я обновлю страницу, я не получу исключение, и вызов Kernel.Get () вернет правильный объект.

Любой совет?

Ответы [ 2 ]

2 голосов
/ 27 августа 2009

(Мы говорили об этом на IRC, но я помещу это здесь на случай, если кто-то еще столкнется с этой проблемой.)

WebsiteSettings имеет [Inject] атрибутов в своих свойствах, поэтому Ninject пытается разрешить привязку из System.String, чтобы ввести значение в свойства. Поскольку вы используете собственный поставщик для активации WebsiteSettings экземпляров, вам не нужны атрибуты [Inject] в его свойствах.

0 голосов
/ 27 августа 2009

Код-нарушитель находился в классе WebsiteSettings, где я делал это:

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

Помещая атрибут Inject в мои свойства, я заставлял Ninject пытаться присвоить значения, которые я никогда не связывал. Поскольку я использую провайдер для загрузки моего типа, мне не нужно включать атрибут Inject.

...