Мы используем эту технику в VB.NET в Visual Studio 2008 ...
Во-первых, проект должен знать, чтобы включить «другие» 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
Поместите этот модуль где-нибудь в вашем проекте и обязательно вызовите метод EnsureInitialized
, чтобы присоединить обработчик AssemblyResolve
до вызова любогодругой код в вашей dll.
ПРИМЕЧАНИЕ: вам нужно заменить [CONTAINER ASSEMBLY] на имя вашей dll.
Также обратите внимание, что приведенный выше код является урезанной версиейчто мы на самом деле используем, потому что наши включают в себя сообщения журнала log4net в стратегических местах.Сообщения регистрации не являются необходимыми для истинной функциональности, поэтому я удалил их для краткости и ясности.
Основным недостатком этого подхода является то, что обработчик AssemblyResolve
должен быть присоединен вручную.Даже если вы не можете настроить все так, чтобы EnsureInitialized
вызывался только один раз во время инициализации потребляющего кода, вы можете вызвать EnsureInitialized
в любом из ваших собственных модулей, для выполнения которых требуется "другая" dll.Это делает код немного более тонким, потому что вы должны помнить, чтобы сделать этот вызов инициализации, но это позволяет вам спать по ночам, зная, что dll будет доступен, когда вам это нужно.
По моему опыту,некоторые «другие» библиотеки не работают хорошо, когда они предоставляются как встроенные ресурсы, поэтому вам может потребоваться немного поиграть, чтобы все заработало.
Последнее примечание: я никогда не использовал компонент ArcMap, поэтомуВаш пробег может меняться!