在.Net应用程序中引用程序集

时间:2010-07-30 10:59:15

标签: .net visual-studio assembly-resolution

在我的应用程序中,我想加载驻留在网络共享上的程序集(应用程序本身也在该共享上),而不必将它们添加到项目的输出路径中。我想要的是一个输出目录,除了应用程序之外什么都没有。

仅将目标目录添加到项目的参考路径中将无效。

我尝试在App.Config中设置探测目录,但这不起作用(甚至在本地diks而不是网络共享上测试)

提前感谢任何提示!

编辑:似乎通过反思引导的方式。使用像NInject这样的依赖注入容器没有更优雅的方法吗?

3 个答案:

答案 0 :(得分:2)

不幸的是,您无法在探测路径中添加任意目录:只是应用程序中的子目录。

但是,可以使用<codeBase>中的<assemblyBinding>元素提供程序集的完整路径。 MSDN page for <assemblyBinding>上有一个例子。缺点是您需要明确列出应用程序引用的所有程序集的路径。

另一种选择是在运行时通过Assembly.LoadFrom加载程序集并通过反射调用方法。如果沿着这条路走下去,你必须阅读Suzanne Cook's blog。如果您没有阅读其他内容,请阅读Choosing a Binding Context

答案 1 :(得分:2)

我来看看Assembly.LoadFrom。您可以编写如下代码:

Assembly myAssembly = Assembly.LoadFrom(assemblyPath);

请注意,您还需要加载任何依赖程序集。 完成后,您可以使用以下命令创建对象:

object myObject = myAssembly.CreateInstance(typeName);

并将其转换为typeName

指定的类型

答案 2 :(得分:0)

如果我理解正确,你想从程序集加载类而不必引用程序集的项目?

然后,您可以使用此类来获取实现/继承某种类型的所有类型:

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

之后,使用John Sibly的答案来创建任何类型的对象动态

干杯!