Ссылки на сборки в приложении .Net - PullRequest
1 голос
/ 30 июля 2010

В моем приложении я хотел бы загрузить сборки, которые находятся на общем сетевом ресурсе (само приложение тоже на этом общем ресурсе) без необходимости добавлять их в выходной путь проекта.Я хотел бы иметь выходной каталог, который почти ничего не содержит, кроме приложения.

Простое добавление целевого каталога в путь ссылки моего проекта не будет работать.

Я попытался установитькаталог исследования в App.Config, но это не сработало (даже проверил его на моих локальных серверах вместо общего сетевого ресурса)

Заранее благодарен за любые подсказки!* РЕДАКТИРОВАТЬ : Кажется, что путь идет через отражение.Разве нет более элегантного способа использования контейнеров Dependency Injection, таких как NInject?

Ответы [ 3 ]

2 голосов
/ 30 июля 2010

Я бы посмотрел на Assembly.LoadFrom.Вы сможете написать некоторый код, подобный следующему:

Assembly myAssembly = Assembly.LoadFrom(assemblyPath);

Обратите внимание, что вам также потребуется загрузить любые зависимые сборки.Когда у вас есть это, вы можете создать как объект, используя:

object myObject = myAssembly.CreateInstance(typeName);

и привести его к типу, указанному typeName

2 голосов
/ 30 июля 2010

К сожалению, вы не можете добавить произвольный каталог к ​​своему пути поиска: только подкаталог в вашем приложении.

Однако, можно предоставить полные пути к сборкам, используя элемент <codeBase> в пределах <assemblyBinding>.На странице MSDN есть пример для <assemblyBinding>.Недостатком является то, что вам нужно будет явно перечислять пути для всех сборок, на которые ссылается ваше приложение.

Другой вариант - загружать сборки во время выполнения через Assembly.LoadFrom и вызывать методы через отражение.Если вы идете по этому пути, вы должны прочитать блог Сюзанны Кук .Если вы больше ничего не читаете, прочитайте Выбор связующего контекста .

0 голосов
/ 30 июля 2010

Если я правильно понимаю, вы хотите загрузить классы из сборки, не ссылаясь на проект сборки?

Тогда вы можете использовать этот класс для получения всех типов, которые реализуют / наследуют определенный тип:

Imports System.IO
Imports System.Threading
Imports Exceptions
Imports System.Reflection
Imports ModuleInterfaces

Public Class StartupLoader
    Private ReadOnly syncroot As New Object

    Private _handler As ExceptionHandler ' custom class to handle exceptions'
    Private _typeToLoad As Type

    Public Sub New(ByVal typeToLoad As Type, _
                   ByVal handler As ExceptionHandler)
        _handler = handler
        _typeToLoad = typeToLoad
    End Sub

    Public Function LoadDLLs() As List(Of Type)
        Dim threads As New List(Of Thread)
        Dim types As New List(Of Type)
        Dim exceptions As New List(Of Exception)
        Dim folders As New Stack(Of String)
        Dim t As Thread

        folders.Push(Directory.GetCurrentDirectory) ' change to your dir here, could use a member var'
        While Not folders.Count = 0
            For Each f In Directory.GetFiles(folders.Peek)
                Dim tmp As String = f
                If tmp.ToLower.EndsWith(".dll") OrElse _
                   tmp.ToLower.EndsWith(".exe") Then
                    t = New Thread(AddressOf LoadDLLsThread)

                    t.Start(New Object() {tmp, types, exceptions})
                    threads.Add(t)
                End If
            Next

            For Each d In Directory.GetDirectories(folders.Peek)
                folders.Push(d)
            Next

            folders.Pop()
        End While

        For Each t In threads
            t.Join()
        Next

        If exceptions.Count > 0 Then
            Throw New ThreadedException(exceptions) ' Custom exception containing a List(Of Exception)'
        End If

        Return types

    End Function

    Private Sub LoadDLLsThread(ByVal vObj As Object)
        Dim objs As Object() = CType(vObj, Object())
        Dim fileName As String = CStr(objs(0))
        Dim globalTypes As List(Of Type) = CType(objs(1), Global.System.Collections.Generic.List(Of Global.System.Type))
        Dim exceptions As List(Of Exception) = CType(objs(2), Global.System.Collections.Generic.List(Of Global.System.Exception))

        Dim types As New List(Of Type)

        Try
            Dim myAssembly As Assembly = Assembly.LoadFrom(fileName)

            For Each t In myAssembly.GetTypes()
                If _typeToLoad.IsAssignableFrom(t) AndAlso _
                   t.IsClass = True AndAlso _
                   t.IsAbstract = False Then
                    types.Add(t)
                End If
            Next

            SyncLock syncroot
                globalTypes.AddRange(types)
            End SyncLock

        Catch ex As Exception
            SyncLock syncroot
                exceptions.Add(ex)
            End SyncLock
        End Try

    End Sub

End Class

После этого используйте ответ Джона Сибли для создания объекта любого типа на лету

Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...