Visual Studio 2008 の VB.NET でこの手法を使用しています...
まず、プロジェクトは、「その他」の dll を埋め込みリソースとして含めることを知る必要があります。ソリューション エクスプローラーで、dll をファイルとして (参照としてではなく) プロジェクトに追加します。次に、ファイルのプロパティを開き、ビルド アクションを「埋め込みリソース」に設定します。他の場所にリンクするのではなく、プロジェクトの構造内に dll ファイルのローカル コピーを作成することをお勧めします。プロジェクトに dll ファイルが含まれたら、その dll のコピーへの参照を追加して、設計時にその内容を使用できるようにします。
これにより、コンパイルされた dll に「その他の」dll が確実に含まれますが、必要なときに自動的に読み込まれることはありません。そこで登場するのが次のコードです。
Public Module Core
Private _initialized As Boolean
Public Sub EnsureInitialized()
If Not _initialized Then
AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf AssemblyResolve
_initialized = True
End If
End Sub
Private Function AssemblyResolve(ByVal sender As Object, ByVal e As ResolveEventArgs) As Assembly
Dim resourceFullName As String = String.Format("[CONTAINER ASSEMBLY].{0}.dll", e.Name.Split(","c)(0))
Dim thisAssembly As Assembly = Assembly.GetExecutingAssembly()
Using resource As Stream = thisAssembly.GetManifestResourceStream(resourceFullName)
If resource IsNot Nothing Then Return Assembly.Load(ToBytes(resource))
Return Nothing
End Using
End Function
Private Function ToBytes(ByVal instance As Stream) As Byte()
Dim capacity As Integer = If(instance.CanSeek, Convert.ToInt32(instance.Length), 0)
Using result As New MemoryStream(capacity)
Dim readLength As Integer
Dim buffer(4096) As Byte
Do
readLength = instance.Read(buffer, 0, buffer.Length)
result.Write(buffer, 0, readLength)
Loop While readLength > 0
Return result.ToArray()
End Using
End Function
End Module
このモジュールをプロジェクトのどこかに配置し、DLL 内の他のコードを呼び出す前にメソッドを呼び出してハンドラーEnsureInitialized
をアタッチしてください。AssemblyResolve
注: [CONTAINER ASSEMBLY] を dll の名前に置き換える必要があります。
また、上記のコードは、戦略的な場所に log4net ロギング メッセージが含まれているため、実際に使用するものを簡略化したものであることに注意してください。ロギング メッセージは実際の機能には必要ないため、簡潔さと明確さのために削除しました。
このアプローチの主な注意点は、AssemblyResolve
ハンドラーを手動でアタッチする必要があることです。EnsureInitialized
消費コードの初期化中に一度だけ呼び出されるように設定できない場合でも、EnsureInitialized
実行に「他の」dll を必要とする独自のモジュール内で呼び出すことができます。これにより、初期化呼び出しを行うことを覚えておく必要があるため、コードが少し複雑になりますが、必要なときに dll が利用できることを知っているので、夜は眠ることができます。
私の経験では、一部の「その他」の dll は、埋め込みリソースとして提供されるとうまく動作しないため、動作させるには少し試してみる必要があるかもしれません。
最終的な注意: ArcMap コンポーネントを使用したことがないため、マイレージは異なる場合があります。