5

私はさまざまなサイトに散らばっているこれらの質問のいくつかにぶつかりました.log4netが「ある」軽量ラッパーの価値に向けてl4nの役人によって答えが紡がれているようです(わかりませんか?)および同様の心構え-驚くべき事実。

しかし、ユーザーが求めているのは (これが私の質問です)、流暢な構成インターフェースで log4net オブジェクト モデルを registertype/registerinstance シーケンスに適合させる方法です。

ここでの目標は、l4n を再ラップすることではなく、流暢なフローをハイジャックする必要のない適切な参照を取得することです。

悪い例: LogManger.GetLogger メソッドから ILog の構成済みインスタンスへの参照を取得し、それを下流のオブジェクトのプロパティに挿入するのに十分早い段階で流暢なフローに入れたいと考えています。

そこで、せっかちな提案に応えて、正規の方法で ILog の通常のインスタンスを作成してみました。

log4net.Config.XmlConfigurator.Configure();
static readonly log4Net.Ilog Log = LogManager.GetLogger(thatlongassemblyreflectionstuff);

そのため、Unity コンテナーへの参照を追加して、私の素晴らしい人生を続けることは、(本当の意味で楽なという意味で) 取るに足らないことのように思えます。

ただし、RegisterInstance メソッドの署名では、インターフェイスではなく「型」が必要です。

log4net オブジェクト モデルを検索していない人は、次のように述べています。l4n は「ラッパー」であり、Log の実際の「タイプ」を取得することはできません。

だから今、私はテストする必要があります。そして、それが何を意味するかを知っています.1分かかるかもしれませんが、1時間か4時間かかる可能性が高いです.

ただし、正規のセットアップに関する省略された部分を除いた以下は機能しました。

container
  .RegisterInstance("Logger", Log, new ContainerControlledLifetimeManager())
.RegisterType<IControllerContext, ControllerContext>
(
   "CtlrCtx", 
   new ContainerControlledLifetimeManager(), 
   new InjectionConstructor(new ResolvedParameter<IMessageBuilder>("MsgBldr")),
   new InjectionProperty("Log",new ResolvedParameter<ILog>("Logger"))
);

したがって、元の Log オブジェクトのハッシュコードと、私の小さな Context オブジェクトのプロパティに挿入された Log オブジェクトのハッシュコードは同じです。

でも...

インジェクション プロセスでは、Context オブジェクトの Log プロパティをそのインターフェイスを介して公開する必要がありました。つまり、これはもはや静的オブジェクトではありません。そして、log4net ILog オブジェクトが静的であるかどうかは、それがシリアライズ可能であり、「ランタイムが不安定になる」という劇的な警告 (マトリックス ファンだけにとって本当に意味がある) なしでアセンブリ間でマッシュできるかどうかに関する決定要因のようです)。

思いとどまるわけではありませんが、Resharper の気の利いた「バッキング フィールドを持つプロパティ」を使用し、バッキング フィールドを静的に設定し、Interface プロパティは非静的のままにしました。うまく構築され、テストは緑色で実行されました。

そのため、再構築も行いましたが、うまくいきました。したがって、これが統合テストに発展するとき、log4net is not serializable の大失敗をこっそり通り過ぎるでしょう。

だから多分これは役立つでしょう

ありがとう

スタート

4

2 に答える 2

5

Unity 2 で InjectionFactory を使用すると役に立ちますか? (この質問を参照してください)。次に、構成コードは次のようになります。

IUnityContainer container = new UnityContainer();
container.RegisterType<ILog>(new InjectionFactory(factory => LogManager.GetLogger()));

次に、通常の Resolve() 呼び出しでロガーを取得します。

ILog logger = container.Resolve<ILog>();
logger.Log(Level.Debug, "Hello world");

ロガーの有効期間を ContainerControllerLifetimeManager に設定してシングルトン インスタンスにすることもできるかもしれませんが、まだ確認していません。

于 2011-02-07T06:00:31.313 に答える
0
ILog logger = container.Resolve<ILog>();
logger.Log(Level.Debug, "Hello world");

実際に機能します。

ただし、クラスにロガーのプロパティがあり、このロガー インスタンスをそれに注入したい場合、それは AFAICT では機能しません。的外れかもしれませんが、ロガー インスタンスを新しいコンテキストで再利用しようとしています。これは元に戻すことができる可能性があるため、注入をあきらめて次の行を追加する必要があるかもしれません

ILog logger = container.Resolve<ILog>();

これにより、すべてのクラスでインスタンス化するよりもわずかに異なるように見える結果が得られます....

私はそれを望んでいた

private ILog Logger {get;set;} 

注入することもできますが、まったく機能していないようです.log4net全体ですべてがインターフェースを介して行われ、具体的なロガーはオズの魔法使いでカーテンの後ろに隠れているためです.

于 2011-06-09T22:44:09.423 に答える