2009-05-14 7 views
17

私は単一のDLLにコンパイルするクラスを作成したいと思います。このDLLは、既存の製品に機能を追加します。バージョンに依存しないDLL参照をクラスに含めることは可能ですか?

このクラスを動作させるために、カスタムクラスは、基になる製品に含まれるDLLを参照します。これらの参照はコンパイルするために必要です。

すべてここでうまくいき、カスタムクラスがコンパイルされます。私は製品に生成されたDLLをドロップすることができ、すべて正常に動作します。

ただし、この製品にはいくつかのバージョン(マイナーバージョン、サービスパック)があります。このDLLを他人に配布したいのですが、DLLが一致する必要があります。完全に製品のバージョンです。完全な一致がない場合は、次のエラーが発生します。

ファイルまたはアセンブリ をロードできませんでした「Product.Web.UI、バージョン= 3.6.1920.2、 ニュートラル文化=、 なPublicKeyToken = dfeaee0e3978ac79 'または に依存します。見つかった アセンブリのマニフェスト定義では、 はアセンブリ参照と一致しません。 (HRESULTからの例外:0x80131040)

バージョン参照について不安なDLLを作成するにはどうすればよいですか?

答えて

4

まだ私の質問に対する答えはありませんが、この回答を使用して解決策を探しているときに見つけたブレッドクラムを記録します。

私はStackOverflowの上多少関連する質問が見つかりました:私は、しかし、根本的な製品を修正する能力を持っていないので、答えは私のために動作しません

Compile a version agnostic .DLL in .NET (Using Manifests?)

を。更新


を私は私よりもはるかに賢く誰かを電子メールで送信し、ここで返信した:

あなたは厳密な名前のアセンブリを参照すると、デフォルトのVisual Studioによって参照に完全なリファレンスを追加アセンブリ。つまり、アセンブリ名、正確なバージョン、文化、公開鍵トークンが含まれています。この情報のいずれかが一致しない場合は、記述された例外がスローされます。

私たちのアセンブリの厳密な名前を削除することは、単にオプションではありません。私は詳細を説明しませんが、MSDNでいくつかの調査を行うことができます。

したがって、参照しているアセンブリのすべてのバージョンに対して回避策を作成する2つの方法があります。

  1. 部分参照が可能です。この記事を参照:http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx
  2. web.configでバインドリダイレクトを使用して互換性のあるバージョンを宣言することができます。この記事を参照してください:http://msdn.microsoft.com/en-us/library/433ysdt1.aspx。 1.あなたはアセンブリがGACにある場合と同じ例外がスローされます、あなたのコントロールを意味し、グローバルアセンブリキャッシュにアセンブリへの部分参照を使用することはできませんので

は、一般的には第二のアプローチが推奨されます。 2.互換性のあるバージョンを明示的に指定します。

-1

VisualStudioで - 参照されているアセンブリ(dll)を右クリックしてプロパティを選択し、 "特定のバージョンが必要です"(またはそれ以上)を設定しましたか? これで問題が解決する場合があります。

アンドレアス

+1

うん、試してみた。私の理解は、この設定はコンパイル時にのみ適用されます。つまり、ビルド中に、コンパイラは発見したDLLのバージョンを知っているわけではありません。 ただし、結果として生じるDLLの場合、これらの非特定のDLL参照は、コンパイルに使用されたDLLに基づいて、厳密な名前のアセンブリ参照(バージョン番号を含む)に変換されます。 –

7

これは優れた解決策です。それは私にとっても同様の問題を解決しました。今までにリンクして死ぬ

Compile a version agnostic DLL in .NET

場合は、キーは以下のようなAppDomain.CurrentDomain.AssemblyResolveイベントを処理することです。アセンブリのバインディングが失敗するとイベントが発生し、バージョンの競合を修正して自分で解決できます。

using System.Reflection; 

static Program() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) 
    { 
     AssemblyName requestedName = new AssemblyName(e.Name); 

     if (requestedName.Name == "Office11Wrapper") 
     { 
      // Put code here to load whatever version of the assembly you actually have 

      return Assembly.LoadFile("Office11Wrapper.DLL"); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 
関連する問題