26

レガシー コード ベースの問題をデバッグしようとしています。Autofac コンテナーから何かを解決できないためにスローされた例外が原因であると思います。ただし、例外がどこかに埋もれていると思いますが、根本的な原因はわかりません。コントローラーから要求されているものが見つからないか、見つけることができる何かが満たすことができない依存関係を持っていると確信しています。ガード句などはありませんので、null参照の問題が発生していると思います。これを試してデバッグするには、コンテナに見つからないすべてのリクエストを確認したいと考えています。

Autofac が解決できなかったすべての要求をログに記録する方法はありますか? または、すべてのリクエストをコンテナに記録するだけですか?

4

3 に答える 3

40

Preparingすべての登録のイベントをキャッチする特別なモジュールを登録することで、コンテナーへのリクエストのログを追加できます。

public class LogRequestsModule : Module
{
  protected override void AttachToComponentRegistration(
    IComponentRegistry componentRegistry,
    IComponentRegistration registration)
  {
    // Use the event args to log detailed info
    registration.Preparing += (sender, args) =>
      Console.WriteLine(
        "Resolving concrete type {0}",
        args.Component.Activator.LimitType);
  }
}

これは最も簡単な方法であり、おそらく必要なものが得られます。イベントが情報をログに記録した直後にPreparing、例外がポップアップ表示され、どのコンポーネントがスローされたかがわかります。

より手の込んだものにしたい場合は、コンテナChildLifetimeScopeBeginningResolveOperationBeginningResolveOperationEnding、およびCurrentScopeEndingイベントにいくつかのイベント ハンドラを設定できます。

  • その間、子の生涯イベントChildLifetimeScopeBeginningに自動的にアタッチするように何かを設定する必要があります。ResolveOperationBeginning
  • その間ResolveOperationBeginning、何が解決されるのかをログに記録します。
  • 発生する例外をログにResolveOperationEnding記録します。
  • ガベージ コレクターがそのすべてのインスタンスで有効期間CurrentScopeEndingスコープをクリーンアップできるように、そのスコープのイベントからサブスクライブを解除する必要があります。

Whitebox プロファイラー プロジェクトには、このより高度なログ記録の一部を実装するモジュールがありますが、最新の Autofac 用に設定されていないため、切り取り/貼り付けのサンプルではなく、出発点として使用する必要があります。

繰り返しますが、最も簡単な解決策は、上に投稿したモジュールです。

于 2013-09-03T19:57:16.873 に答える
32

将来誰かに役立つ場合に備えて、Travisによる優れた回答に基づいて構築するだけです。

クラス構造が非常に深い場合、コンポジション階層でオブジェクトを表示すると、問題のあるパスを見つけやすくなります。これは、次のような方法で実現できます。

using System;
using System.Text;
using Autofac;
using Autofac.Core;

namespace Tests
{
    public class LogRequestModule : Module
    {
        public int depth = 0;

        protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,
                                                              IComponentRegistration registration)
        {
            registration.Preparing += RegistrationOnPreparing;
            registration.Activating += RegistrationOnActivating;
            base.AttachToComponentRegistration(componentRegistry, registration);
        }

        private string GetPrefix()
        {
            return new string('-',  depth * 2);
        }

        private void RegistrationOnPreparing(object sender, PreparingEventArgs preparingEventArgs)
        {
            Console.WriteLine("{0}Resolving  {1}", GetPrefix(), preparingEventArgs.Component.Activator.LimitType);
            depth++;
        }

        private void RegistrationOnActivating(object sender, ActivatingEventArgs<object> activatingEventArgs)
        {
            depth--;    
            Console.WriteLine("{0}Activating {1}", GetPrefix(), activatingEventArgs.Component.Activator.LimitType);
        }
    }
}

出力例:

--Resolving  SomeProject.Web.Integration.RestApiAdapter.RestApiAdapter
----Resolving  SomeProject.Web.Integration.RestApiAdapter.Client.ClientFactory
------Resolving  SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
------Activating SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
------Resolving  SomeProject.Web.Integration.RestApiAdapter.Client.Authentication.ApiClientAuthenticationService
--------Resolving  SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
--------Activating SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
------Activating SomeProject.Web.Integration.RestApiAdapter.Client.Authentication.ApiClientAuthenticationService
于 2014-04-30T16:27:38.630 に答える