2009-07-01 26 views
2

私はlog4netのアペンダで作業しています。クラスライブラリのlog4netバージョンの依存関係をどのように管理するかという問題に直面していますサイト。私のクラスライブラリはlog4net dllを参照しなければならないので、ビルド時に私が参照しているバージョンに結びついてしまいます。しかし、このコンポーネントがデプロイされるサイトには、log4netのさまざまなバージョンが用意されています。古いものもあれば、古いものもあれば、新しいものもあります。私はこの問題にどのようにアプローチすべきですか?私はlog4netの新しいバージョンごとに新しいバージョンのアペンダーをリリースし、ユーザーに正しくマッチさせるという負担をかけたくありません。私はまた、アペンダーのユーザーに複雑な並列マニフェストのやり方を依頼したくありません。私はアペンダーを単純にエンドユーザーの場所にコピーし、そこに存在するlog4netバージョンがあればすぐに作業することができます。管理対象クラスライブラリのバージョンに依存しない参照依存関係

これは達成可能ですか?私は明白な何かを欠いていますか

更新

だけの作業ソリューションはマニフェストを使用することです。 2つの「自家製」log4netのビルドと、次の構成セクションを追加すると、私の問題を解決して私がテストした:

なPublicKeyTokenは、実際のlog4netのアセンブリの実際のキートークンです
<runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
      <assemblyIdentity name="log4net" 
           publicKeyToken="..." 
           culture="neutral" /> 
      <bindingRedirect oldVersion="1.2.10.0" 
          newVersion="..."/> 
     </dependentAssembly> 
     </assemblyBinding> 
    </runtime> 

、1.2.10は私のアペンダが構築されているバージョンでありますwithとnewVersionはサイト上に現在展開されているバージョンです。このセクションは、配備されたappconfigまたはwebconfigに追加することができます(マシン設定でも実行できますが、推奨しません...)。

答えて

2

多くのプロジェクトは、あなたが今説明したのと同じ問題を抱えています。私が知る限り、これはあなたが出版社としてコントロールできるものではありません。 publisher policyを設定すると、以前のバージョンのアセンブリが参照されている場合に特定のバージョンのアセンブリを使用するように自動的に指定できますが、制御しないアセンブリ(log4netなど)にはこれを指定する方法はありません。

ユーザーは、assembly redirectを介して特定のバージョンにリダイレクトされるlog4netの古いバージョン(アセンブリが参照する可能性があります)の要求を指定できます。

+0

私はあなたの答えは正しいと知っていますが、私が避けようとしている問題の1つです(お客様にマニフェストファイルを編集させてください)。 –

0

EDIT:以下の提案が動作しない:特定のバージョンは、コンパイル時に適用されて、いない実行時間

Visual Studioでのlog4netへの参照を選択します(Visual Studioを使用していると仮定し!)プロパティを表示します。 「特定のバージョン」を「偽」に設定すると、になるはずです。あなたはすでにそれを試して問題に遭遇しましたか?

+0

9年間の* .Net *私はそれを試してみましょう。 –

+0

これはあなたのために働くかどうか私は本当に知りたいです。私が正しく覚えていれば、Fluent NHibernate(またはNHibernate自体である)は、OPに記述されている問題のためlog4netへの依存をなくしました。 –

+0

log4net v1.2に依存している「ソフト」依存のアペンダーDLLを残しました。私は新しいlog4net v1.9をコンパイルし、テストを実行しました。添付ファイルを読み込めませんでした。メッセージ「ファイルまたはアセンブリを読み込めませんでした。log4net、バージョン= 1.2.10.0、...」。私はまた別の方法(アペンダーは私の 'v1.9'、ランタイムv1.2上に構築された)を利用して無駄にしようとしました。私は強い名前、同じ結果を削除しました。 http://bit.ly/4ViOaに基づいて、問題の「False」はコンパイル時にのみ適用されると思います。 –

0

設定ファイル(またはコードスニペット)で定義されているように、あなたが使用するインターフェイスによると、実際にあなたのために必要なクラスをインスタンス化(などCastleSpring.net、など)IoCコンテナを使用することができます。
この方法では、インターフェイスのみで作業し、具体的なクラスによる実際のバインディングはコンテナ(フレームワーク)によって行われます。これは、dependency injectionFowler's articleも参照してください)を使用して作業すると(特に)達成できます。
使用しているインターフェイスが同じであれば、コードに「レイトバインディング」が適用されます。あなたがに、AssemblyResolveイベントを処理することができ

+0

Log4net基本クラス/インタフェースにタイプ依存があるかどうかは関係ありません。 IoCが動作するためには、log4netは、タイプを、私が参照できるv1.0で保持されている別の不変のdllに分割する必要があります。 –

+0

ログ用に独自のインターフェイスを作成してください。 log4netのシグニチャと同じシグネチャを持つことができます(この方法では、コードはほとんど変更されません)。その後、IoCコンテナを使用できます。これも見てください:http://tinyurl.com/l7xmd2 –

+0

私はあなたが私の問題を理解しているとは確信していません。 * log4net *を使用するサードパーティによってロードされるコンポーネントが必要です。私はlog4netの代わりに私のログを使用してそれらに興味がない、それは私がすでに解決した簡単なケースのシナリオです。 –

2

AppDomain current = AppDomain.CurrentDomain; 
current.AssemblyResolve += current_AssemblyResolve; 

あなたは、バージョン番号を削除し、そのバージョンを指定せずにアセンブリをロードするために(ResolveEventArgsから)Nameプロパティに文字列操作を使用することができます。

0

単純で愚かな解決策は、vb.netで書かれたプロキシライブラリを使用することです。

私はMS OFFICE用のツールを作成しようとしていたときに同様の問題に直面しました。

VBでは、どのバージョンのオフィスがインストールされているか心配していませんでした。

0

私は、ユニットテストフレームワーク、ロギングフレームワーク、コード生成ツールのような 'インフラストラクチャ'ライブラリに依存するライブラリを嫌う傾向があります。

もしあなたがGACにインストールできるライブラリに頼っていたら、それを頼りにしてライブラリの複数バージョンを一度にアクティブにすることができましたが、これはlog4netとうまくいっていない可能性があります構成状態モデルが一般的に使用されています)、ライブラリを使用する上で非常に複雑です。

多くのライブラリは、ユーザーの要件を十分に予測することができないため、何らかのログを出力しないようにする必要があります。しかし、log4netの実行時設定機能はこれをある程度緩和します。フレームワークに組み込まれているトレースAPIを使用するとコードが改善されるでしょうか?結果として生成されるコードは、依存関係の観点からはるかに軽量になり、さらに高度なチューニング・ポスト・コンパイルが可能になります。

0

これは別の回答です。ハッキー、そして合併症があるかもしれませんが:

dllにlog4netコードをビルドします。
オープンソースであり、reasonably permissive licenceの下では、コードに使用可能で消費者を妨げないように、可視性(オプションで名前空間)を変更するようにファイルを編集することができます。

アプリケーションの残りの部分と同じ場所からライブラリを構成しようとするコードを追加することもできます。また、完全に別のファイル/構成セクションからライブラリのログを構成することもできます。

+0

私のアペンダーは間違ったインターフェース(同じ名前ですが、異なるアセンブリから別のタイプのもの)を公開するので、できません。 –

+0

ああ、あなたはそれを拡張しているだけではありません。あなたは質問でそれを明確にしたいかもしれません – ShuggyCoUk

0

CAD/CAMアプリケーションでは、私たちがサポートしなければならなかったサードパーティのマシン用のサポートライブラリがいくつかありました。私は何をしましたか?2つのアセンブリを1つのバージョンにリンクし、もう1つを他のバージョンにリンクしました。私はそれらを同じインターフェースの後ろに置きます。

設定ダイアログでは、使用するバージョンを指定できます。もちろん、間違ったバージョンが使用されると、エラーが発生します。

このトリックはインターフェイスを作成しているため、両方のアセンブリがシームレスに動作できるようになっています。 Microsoft Officeのような複雑なAPIをラップすることはできないかもしれません。その場合は、APIの使用をバックトラックし、最小限の呼び出し数が使用されている場所を確認し、その時点でインターフェイスを構築する必要があります。

私の場合は、マテリアルシートをマシンにダンプしなければならないときがありました。そこで私は、そのマシンとシートオブジェクトを取得したルーチンのためのルーチンを設定ダイアログを持つインターフェースを作成しました。すべてがそのクラスに住んでいた。

あなたの場合は、Log4netで何を使用しているかを見て、その周りにインターフェイスを構築できるかどうかを確認する必要があります。

これを行う利点の1つは、もはやLog4Netに溶接されないことです。インターフェイスを正しく設計してから、別のパッケージを再実装することができます。さらに、インターフェースを作成することで、アプリケーションがLog4netとどのように対話するかを正確に定義します。最後に、Log4Netが壊れた変更を実装した場合、それに対処するための道があります。

0

それが原因バージョン1.2.10.0とlog4netのの1.2.11.0間なPublicKeyTokenの変化に、このbindingRedirectが理由のために、これらの2つのバージョンがherehereを議論の間では不可能に近付いている、ということは注目に値します。

NuGetを使用している場合は、からoldkeyバージョンのlog4netをダウンロードするためにNuGetを迂回する必要があるため、これはさらに問題になります。

はしかし、私もこれはaforementioned linkに述べた理由について次の例外で失敗していることが見つかりました:

見つからない方法:「ボイドlog4net.Config.BasicConfigurator.Configure()」