1

私のアプリケーションでは、プロジェクトの出力パスに追加せずに、ネットワーク共有に存在するアセンブリ(アプリケーション自体もその共有上にあります)をロードしたいと思います。私が欲しいのは、アプリケーション以外はほとんど含まれていない出力ディレクトリです。

プロジェクトの参照パスにターゲットディレクトリを追加するだけでは機能しません。

App.Configでプローブディレクトリを設定しようとしましたが、機能しませんでした(ネットワーク共有ではなく、ローカルのdikでテストした場合でも)

ヒントを事前に感謝します!

編集:これが進んでいる方法は、反省を通してつながるようです。NInjectのような依存性注入コンテナを使用するよりエレガントな方法はありませんか?

4

3 に答える 3

2

残念ながら、プロービングパスに任意のディレクトリを追加することはできません。アプリケーション内のサブディレクトリのみです。

<codeBase>ただし、内の要素を使用してアセンブリへのフルパスを提供することは可能<assemblyBinding>です。のMSDNページに<assemblyBinding>例があります。欠点は、アプリケーションが参照するすべてのアセンブリのパスを明示的にリストする必要があることです。

もう1つのオプションは、実行時にアセンブリをロードしAssembly.LoadFrom、リフレクションを介してメソッドを呼び出すことです。このルートをたどる場合は、SuzanneCookのブログを読む必要があります。他に何も読んでいない場合は、「バインディングコンテキストの選択」をお読みください。

于 2010-07-30T11:05:50.090 に答える
2

Assembly.LoadFromを見てみましょう。次のようなコードを書くことができます。

Assembly myAssembly = Assembly.LoadFrom(assemblyPath);

依存するアセンブリもロードする必要があることに注意してください。これを取得したら、次を使用してオブジェクトとして作成できます。

object myObject = myAssembly.CreateInstance(typeName);

そして、typeNameで指定されたタイプにキャストします

于 2010-07-30T11:12:38.347 に答える
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の回答を使用して、任意のタイプのオブジェクトをその場で作成します

乾杯 !

于 2010-07-30T12:42:47.967 に答える