문제

내 소프트웨어에서 동적으로 로드 가능한 플러그인을 생성하는 방법을 제공하고 싶습니다.이를 수행하는 일반적인 방법은 다음을 사용하는 것입니다. 로드라이브러리 DLL을 로드하고 호출하는 WinAPI 함수 GetProc주소 해당 dll 내부의 함수에 대한 포인터를 가져옵니다.

제 질문은 C#/.Net 애플리케이션에서 플러그인을 어떻게 동적으로 로드합니까?입니다.

도움이 되었습니까?

해결책

다음 코드 조각(C#)은 다음에서 파생된 구체적인 클래스의 인스턴스를 생성합니다. Base 애플리케이션 경로의 클래스 라이브러리(*.dll)에서 찾아 목록에 저장합니다.

using System.IO;
using System.Reflection;

List<Base> objects = new List<Base>();
DirectoryInfo dir = new DirectoryInfo(Application.StartupPath);

foreach (FileInfo file in dir.GetFiles("*.dll"))
{
    Assembly assembly = Assembly.LoadFrom(file.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        if (type.IsSubclassOf(typeof(Base)) && type.IsAbstract == false)
        {
            Base b = type.InvokeMember(null,
                                       BindingFlags.CreateInstance,
                                       null, null, null) as Base;
            objects.Add(b);
        }
    }
}

편집하다: 에서 참조하는 클래스 매트 아마도 .NET 3.5에서는 더 나은 옵션일 것입니다.

다른 팁

.NET 3.5부터 .NET 애플리케이션에서 플러그인을 생성하고 로드하는 공식화된 기본 방식이 있습니다.그것은 모두에 있습니다 시스템.애드인 네임스페이스.자세한 내용은 MSDN에서 다음 문서를 확인하세요. 추가 기능 및 확장성

플러그인을 동적으로 로드하기

.NET 어셈블리를 동적으로 로드하는 방법에 대한 자세한 내용은 다음을 참조하세요. 이 질문 (그리고 내 대답).다음은 생성을 로드하는 코드입니다. AppDomain 그 안에 어셈블리를 로드합니다.

var domain = AppDomain.CreateDomain("NewDomainName");
var pathToDll = @"C:\myDll.dll"; 
var t = typeof(TypeIWantToLoad);
var runnable = domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName) 
    as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

플러그인 언로드

플러그인 프레임워크의 일반적인 요구 사항은 플러그인을 언로드하는 것입니다.동적으로 로드된 어셈블리를 언로드하려면(예:플러그인 및 추가 기능) 포함된 항목을 언로드해야 합니다. AppDomain.자세한 내용은 다음을 참조하세요. AppDomains 언로드에 대한 MSDN의 이 기사.

WCF 사용

이있다 스택 오버플로 질문과 답변 WCF(Windows 통신 프레임워크)를 사용하여 플러그인 프레임워크를 만드는 방법을 설명합니다.

기존 플러그인 프레임워크

나는 두 가지 플러그인 프레임워크를 알고 있습니다.

어떤 사람들은 다음에 대해 이야기합니다. MEF(관리형 확장성 프레임워크) 플러그인 또는 추가 기능 프레임워크로는 그렇지 않습니다.자세한 내용은 다음을 참조하세요. 이 StackOverflow.com 질문 그리고 이 StackOverflow.com 질문.

한 가지 팁은 실행 중인 코드가 잠재적으로 악성일 수 있으므로 모든 플러그인 등을 자체 AppDomain에 로드하는 것입니다.자체 AppDomain을 사용하여 로드하지 않으려는 어셈블리 및 유형을 "필터링"할 수도 있습니다.

AppDomain domain = AppDomain.CreateDomain("tempDomain");

그리고 애플리케이션 도메인에 어셈블리를 로드하려면 다음을 수행합니다.

AssemblyName assemblyName = AssemblyName.GetAssemblyName(assemblyPath);
Assembly assembly = domain.Load(assemblyName);

애플리케이션 도메인을 언로드하려면 다음을 수행합니다.

AppDomain.Unload(domain);

예, Matt 및 System.AddIn에 대한 ++(System.AddIn에 대한 두 부분으로 구성된 MSDN 잡지 기사를 사용할 수 있습니다) 여기 그리고 여기)..NET Framework가 미래에 어디로 갈지 알아보기 위해 살펴볼 수 있는 또 다른 기술은 다음과 같습니다. 관리형 확장성 프레임워크 현재 Codeplex에서 CTP 형식으로 제공됩니다.

기본적으로 두 가지 방법으로 할 수 있습니다.

첫 번째는 kernel32.dll을 가져오고 이전에 사용한 것처럼 LoadLibrary 및 GetProcAddress를 사용하는 것입니다.

[DllImport("kernel32.dll")]

internal static extern IntPtr LoadLibrary(String dllname);

[DllImport("kernel32.dll")]

internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

두 번째는 .NET 방식으로 수행하는 것입니다.반사를 사용하여.System.Reflection 네임스페이스와 다음 메서드를 확인하세요.

먼저 경로로 어셈블리를 로드한 다음 이름으로 유형(클래스)을 가져온 다음 다시 이름으로 클래스의 메서드를 가져오고 마지막으로 관련 매개 변수를 사용하여 메서드를 호출합니다.

이 기사는 약간 오래되었지만 애플리케이션 내에서 확장성 레이어를 생성하는 데 여전히 적용 가능합니다.

사용자가 매크로 및 플러그인을 사용하여 .NET 애플리케이션에 기능을 추가하도록 허용

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top