Autofac记录模块& ASP.Net Web窗体中已解析的参数

时间:2017-07-16 14:42:14

标签: c# asp.net webforms autofac nlog

我正在尝试使用Autofac模块将NLog记录器注入到asp.net Web窗体应用程序(代码隐藏),但在尝试使用ResolvedParameter时遇到错误:

全球性的asax&记录模块:

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.RegisterModule<LoggingModule>();
        _containerProvider = new ContainerProvider(builder.Build());

    }
}

 public class LoggingModule : Module
 {
     protected override void Load(ContainerBuilder builder)
     {
         builder.Register(RegsiterFunc).AsImplementedInterfaces();
     }

     private NLogger RegsiterFunc(IComponentContext arg, IEnumerable<Parameter> parameters)
     {
         return new NLogger(parameters.TypedAs<Type>());
     }

    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing +=
            (sender, args) =>
            {
                var forType = args.Component.Activator.LimitType;

                var logParameter = new ResolvedParameter(
                    (p, c) => p.ParameterType == typeof(ILogger),
                    (p, c) => c.Resolve<ILogger>(TypedParameter.From(forType)));

                 args.Parameters = args.Parameters.Union(new[] { logParameter });
            };
    }


}

NLogger类:

public class NLogger : ILogger
    {
        private readonly Logger m_Logger;

        public NLogger(Type type)
        {
            m_Logger = LogManager.GetLogger(type.FullName);
        }

        public NLogger(string typeName)
        {
            m_Logger = LogManager.GetLogger(typeName);
        }

    .......
}

幕后的Aspx页面代码:

public partial class _Default : Page
{
    public ILogger m_Logger { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        m_Logger.Error("test");
    }
}

根据我正在使用ResolvedParameter的请求类型启动日志。

RegsiterFunc中的 parameters.TypedAs()行引发异常:“序列不包含任何元素”。

相同的代码在asp.net MVC应用程序中有效,但在Web表单项目中失败。

  

发生System.InvalidOperationException HResult = 0x80131509   Message = Sequence不包含元素Source = Autofac   StackTrace:在Autofac.ParameterExtensions.ConstantValue [TParameter,TValue](IEnumerable`1参数,Func`2谓词)   at Autofac.ParameterExtensions.TypedAs [T](IEnumerable`1参数)   在Global.asax.cs中的WebApplication1.LoggingModule.RegsiterFunc(IComponentContext arg,IEnumerable`1参数):第55行   在Autofac.Builder.RegistrationBuilder。&lt;&gt; c__DisplayClass0_0`1.b__0(IComponentContext c,IEnumerable`1 p)   在Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context,IEnumerable`1参数)   在Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1参数)

1 个答案:

答案 0 :(得分:2)

据我了解,在RegsiterFunc中,您正在尝试检索记录器正在注入的组件类型。

但是携带组件类型的参数不是TypedParameter,而是NamedParameter。这就是你得到例外的原因。

虽然不那么优雅,但RegsiterFunc的工作版本:

private NLogger RegsiterFunc(IComponentContext arg, IEnumerable<Parameter> parameters)
{
    var type = (Type)((NamedParameter)parameters.First()).Value;
    return new NLogger(type);
}

然后,对于Default.aspx页面,传递给NLogger的类型将为ASP.default_aspx

您创建的第二个参数:

new ResolvedParameter(
    (p, c) => p.ParameterType == typeof(ILogger),
    (p, c) => c.Resolve<ILogger>(TypedParameter.From(forType)));

未使用,因此无需覆盖AttachToComponentRegistration