2010-07-30 72 views
1

在我的應用程序中,我想加載駐留在網絡共享上的程序集(應用程序本身也在該共享上),而無需將它們添加到項目的輸出路徑中。我想要的是一個輸出目錄,除了應用程序之外什麼都沒有。在.Net應用程序中引用程序集

僅僅將目標目錄添加到我的項目的參考路徑將不起作用。

我嘗試設置在App.config探測目錄,但沒有奏效提前(甚至測試它在我的本地diks而不是網絡共享)

感謝任何提示!

編輯:似乎這是通過反思的方式。沒有更好的方式使用像NInject這樣的依賴注入容器嗎?

+0

在大多數情況下,讓輸出路徑中的所有程序集都不像第一眼那樣糟糕。那麼,爲什麼你認爲你需要以不同的方式做呢? – 2010-07-30 11:12:02

+0

基本上你是對的 - 不傷害他們不會讓他們在那裏。但是我們有一個接近12個前端的地方,它使用1.2.x版本中的一個庫,另外三個需要1.2.y(或者任何其他版本,只是給出隨機數)。因此,我們正在從這些庫中提取接口(以嵌入到項目中)並從應用程序中刪除實現程序集(將它們放到網絡上以動態加載)。這種方法的優點是,當需要庫的錯誤修正時,我們甚至不必重新編譯我們的應用程序 - 界面保持不變。 – 2010-08-02 06:22:59

+0

Ninject不會給你任何你不能通過代碼做的事情。爲了使用Ninject(和其他DI容器),您必須能夠以某種方式加載程序集。 – 2010-08-02 07:27:16

回答

2

不幸的是,你不能添加一個任意目錄到你的探測路徑:只有你的應用程序中的一個子目錄。

但是,可以使用<assemblyBinding>中的<codeBase>元素提供組件的完整路徑。 MSDN page for <assemblyBinding>上有一個例子。缺點是你需要明確列出你的應用程序引用的所有程序集的路徑。

另一種選擇是在運行時通過Assembly.LoadFrom加載程序集並通過反射調用方法。如果沿着這條路線走,你必須閱讀Suzanne Cook's blog。如果你什麼也沒讀,請閱讀Choosing a Binding Context

2

我會看看Assembly.LoadFrom。您可以編寫如下代碼:

Assembly myAssembly = Assembly.LoadFrom(assemblyPath); 

請注意,您還需要加載任何相關程序集。 一旦你有了這個,你可以使用的對象創建:

object myObject = myAssembly.CreateInstance(typeName); 

並將其強制通過的typeName

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 

之後,用約翰Sibly的回答對飛創建任何類型的對象

乾杯!

相關問題