2009-04-12 3 views
4

나는 .NET과 함께 플러그인 시스템을 만들려고 노력하고 있는데, 제대로하고 있는지 확실하지 않습니다. 이 시스템의 기본은 특정 디렉토리 ({apppath}/Plugins /)에 여러 개의 미리 컴파일 된 DLL이 있으며, 리플렉션을 통해 각 클래스를 살펴보고 가능한 모든 클래스에 대해 특정 기본 클래스를 상속 받기를 원합니다. (이것은 또 다른 DLL에 정의되어 있지만 나중에 설명하겠다.) 그런 다음 인스턴스를 만들고 해당 인스턴스에서 특정 함수를 호출한다.Createinstance() -이 작업을 수행하고 있습니까?

Public Sub ScanPluginsInDirectory(ByVal Directory As String) 

    Dim Plugins As New IO.DirectoryInfo(Directory) 
    Dim Files As IO.FileInfo() = Plugins.GetFiles("*.dll") 
    Dim CryptType As Type = GetType(CryptPluginBase) 
    Dim PluginsData as List(Of LoadedPluginsInfo) 

    For Each DllFile As IO.FileInfo In Files 
     Try 
      Dim thisAsm As Assembly = Assembly.LoadFrom(DllFile.FullName) 
      Dim ClassDefs = thisAsm.GetTypes().Where(Function(type) CryptType.IsAssignableFrom(type)) 

      For Each ClassDef As Type In ClassDefs 
       Dim A As Object 
       A = ClassDef.Assembly.CreateInstance(ClassDef.Name) 
       PluginsData.Add(New LoadedPluginsInfo(A.Plugin(), False)) 
      Next 
     Catch ex As Exception 
      Continue For 
     End Try 
    Next 
End Sub 

내가 가진 특정 문제는 이것이 올바른 방법임을 확신하지 못합니다. A.Plugin()이 실제로 존재하고 여기에서 참조 된 구조와 클래스가 버그가 없다고 가정 할 수 있다면 메서드를 사용하려고합니까? 도움을주기 위해 더 많은 코드가 필요할 경우 게시 할 수 있습니다.

답변

3

전체적으로 전략이 효과적입니다. Assembly.LoadFrom 호출은 대상 어셈블리를 프로세스로로드합니다. 거기에서 유형 검사를 수행하고 해당 유형의 인스턴스를 작성할 수 있습니다.

나는 인스턴스를 만드는 가장 쉽고 신뢰할 수있는 방법은 Activator.CreateInstance 메서드를 사용하는 것이라고 생각합니다.

For Each def As Type in ClassDefs 
    Dim inst = Activator.CreateInstance(def) 
    PluginsData.Add(new LoadedPluginsInfo(inst.Plugin(), False)) 
Next 

목표에 따라 Try/Catch 블록을 벗어나지 않고 루프로 이동하는 것이 좋습니다. 루프 밖에서 Try/Catch 블록을 사용하면 어셈블리의 특정 유형에 오류가있는 경우 해당 어셈블리의 모든 유형을 삭제합니다. 내부로 이동하면 expect.d로 작동하지 않는 유형 만 삭제할 수 있습니다. 현재의 동작이 의도 일 수 있습니다.

+0

inst.Plugin()을 의미합니까? – Sukasa

+0

@Sukasa, 네. 나는 그것을 바로 잡았다. – JaredPar

+1

좋아, 내가 알지 못하는 작은 트릭이 있는지 확실하지 않았다. 감사! – Sukasa

1

이 작업은 이전에 일부 프로젝트에서 사용하고있었습니다. 나는 구체적으로 생성자를 찾고 호출했다. 그러나 그 점을 제외하고는 같은 생각이었다.

그러나 플러그인 아키텍처를 위해 많은 것을 처리하는 MEF을보고 싶을 수도 있습니다 (릴리스 버전을 조금이라도 기다리고 싶다면 아직 CTP입니다).

관련 문제