2

我刚开始第一次使用依赖注入,我在一个 ASP.NET MVC 2 网站中使用 Ninject 2.0 作为我的 IoC 容器,我遇到了一个我不知道如何应对的激活错误。我相信这很简单,所以希望有人可以在没有太多思考的情况下指出我正确的方向。

我的类 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 集合正确初始化。尽管如此,当应用程序第一次加载时:

“/”应用程序中的服务器错误。
使用 SByte* 的隐式自绑定激活 SByte* 时出错
没有构造函数可用于创建实现类型的实例。

激活路径:
 4) 将依赖 SByte* 注入到 string 类型的构造函数的参数值中
 3) 将依赖字符串注入到 WebsiteSettings 类型的属性 WebsiteName
 2) 将依赖项 IWebsiteSettings 注入 HomeController 类型的属性 WebsiteSettings
 1) 请求 HomeController

建议:
 1) 确保实现类型具有公共构造函数。
 2) 如果您已经实现了单例模式,请改用 InSingletonScope() 的绑定。

有趣的是,如果我刷新页面,我不会收到异常,并且对 Kernel.Get() 的调用会返回正确的对象。

有什么建议吗?

4

2 回答 2

2

(我们在 IRC 上讨论过这个问题,但我把它放在这里以防其他人也遇到这个问题。)

WebsiteSettings在其属性上具有[Inject]属性,因此 Ninject 正在尝试解析绑定System.String以将值注入属性。由于您使用自定义提供程序来激活WebsiteSettings实例,因此您不需要[Inject]其属性上的属性。

于 2009-08-26T22:05:50.397 回答
0

有问题的代码实际上是在我正在执行此操作的类 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 尝试分配我从未绑定的值。因为我使用 Provider 来加载我的类型,所以不需要包含 Inject 属性。

于 2009-08-26T22:06:13.937 回答