2017-07-16 7 views
1

NogLoggerをasp.net Webフォームアプリケーション(コードビハインド)に注入するためにAutofacモジュールを使用しようとしていますが、試行中にエラーが発生します。AutofacロギングモジュールとASP.Net Webフォームで解決されたパラメータ

グローバル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クラス:

ResolvedParameterを使用するには後ろの210
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のTypes.TypedAs()は「シーケンスに要素がありません」という例外をスローします。

同じコードはasp.net MVCアプリケーションで動作しますが、Webフォームプロジェクトでは失敗します。

のSystem.InvalidOperationExceptionが発生HRESULT = 0x80131509 メッセージ=配列には要素出典= Autofacを含まない のStackTrace:Autofac.ParameterExtensions.ConstantValue【のTParameter、TValue(IEnumerableを` 1パラメータのFunc ` 2述語) ででAutofac.ParameterExtensions.TypedAs [T] Global.asax.csでWebApplication1.LoggingModule.RegsiterFunc(IComponentContext引数、IEnumerableを` 1パラメータ)で(IEnumerableを` 1パラメータ) :Autofac.Builder.RegistrationBuilderでライン55 。 <> c__DisplayClass0_0 ` 1.b__0(IComponentContextのC、IEnumerableを` 1 P)Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstanceで (IComponentContextコンテキスト、IEnumerableを` 1パラメータ)Autofac.Core.Resolving.InstanceLookup.Activateで ( IEnumerableを` 1パラメータ)私の知る限り理解し

答えて

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になります。

作成した二番目のパラメータ:AttachToComponentRegistrationをオーバーライドすることは不要であるように

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

は、使用されていません。

+0

素晴らしい解決策、あなたのコードは動作しています。私は "注入された"(ソース)コンポーネントのタイプがAttachToComponentRegistrationステージでのみ利用可能であると考えました。 NamedParameterも使用していますが、このパラメータは使用前に設定されていません。ソースコンポーネントのタイプは、最初に指定されたパラメータとして常に自動的に使用可能ですか? – RuSh

関連する問題