【问题标题】:Autofac with WebForms public property throws constructor exception具有 WebForms 公共属性的 Autofac 引发构造函数异常
【发布时间】:2016-03-15 01:53:38
【问题描述】:

我正在尝试修改现有的 WebForms 应用程序并希望使用 Autofac。据我所知,我已经根据文档 (http://autofac.readthedocs.org/en/latest/integration/webforms.html#structuring-pages-and-user-controls-for-di) 设置了应用程序。

具有公共属性的网页代码

public partial class MyTestPage : Page
{
    public ILogger Logger { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        //page load code here

web.config

<modules>
<add name="ContainerDisposal" type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web" preCondition="managedHandler" />
  <add name="PropertyInjection" type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web" preCondition="managedHandler" />
</modules>          

Global.asax.cs

public class Global : HttpApplication, IContainerProviderAccessor
{
        static IContainerProvider _containerProvider;

        public IContainerProvider ContainerProvider
        {
            get { return _containerProvider; }
        }


    void Application_Start(object sender, EventArgs e)
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<Logger>().As<ILogger>().InstancePerRequest();
        _containerProvider = new ContainerProvider(builder.Build());

    }

当我尝试加载页面时,Autofac 抛出此异常。

无法使用构造函数查找器“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”找到类型为“NLog.Logger”的构造函数。

我在这里缺少什么?为什么 Autofac 寻找构造函数而不是获取公共属性?

【问题讨论】:

    标签: asp.net webforms autofac


    【解决方案1】:

    这里的问题是 Autofac 正在尝试创建 Logger 类的实例以将其注入您的 MyTestPage。它尝试使用默认的、无参数的构造函数,这是不可用的。所以问题不在于您的页面,而在于您的记录器注册。

    我对@9​​87654326@ 不熟悉,但是根据教程,您应该使用LogManager 创建Logger 的实例,例如

    Logger logger = LogManager.GetCurrentClassLogger();
    

    Logger logger = LogManager.GetLogger("MyClassName");
    

    所以你应该把你的注册改成这样(未经测试):

    builder.Register(c => LogManager.GetCurrentClassLogger()).As<ILogger>().InstancePerRequest();
    

    如上所述,我对 NLog 并不熟悉,但我假设 NLog Logger 类实现了ILogger 接口。

    编辑:

    This 模块应该处理您想要实现的目标。

    【讨论】:

    • 这确实解决了异常,但它创建了所有名称为“global”的记录器,这对记录没有用处。这使我处于与此相关问题(stackoverflow.com/questions/28443955/…)相同的情况。我在回答那个问题时尝试过这种方法,但它让我在这个问题上遇到了例外。
    • 我不确定你想在这里实现什么...你想在解决它时以某种方式设置记录器类吗?
    • 在没有 DI 的情况下执行此操作看起来像这样。 public partial class MyTestPage : Page { protected static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); 当记录器记录某些内容时,记录器名称将是“MyTestPage”。所以我需要注入它,但让 GetCurrentClassLogger() 在网页的上下文中执行,而不是 global.asax.cs 的上下文。
    • 我认为这个 nuget 包可以解决你的问题:github.com/ziyasal/Autofac.Extras.NLog。您应该注册NLogModule,如文档中所示。您可以查看源代码,了解它是如何处理的——它类似于您在第一条评论中链接的 SO 问题。我已经编辑了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多