[C#] 런타임에 .NET 어셈블리를로드하고 이름 만 알고있는 유형을 인스턴스화 할 수 있습니까?

프로젝트의 어셈블리에 대한 참조를 추가하지 않고 DLL 이름과 클래스 이름 만 가지고 있으면 런타임에 객체를 인스턴스화 할 수 있습니까? 클래스는 인터페이스를 구현하므로 클래스를 인스턴스화하면 인터페이스로 캐스트합니다.

어셈블리 이름 :

library.dll

유형 이름 :

Company.Project.Classname


편집 : DLL의 절대 경로 Assembly.LoadFile가 없으므로 작동하지 않습니다. DLL은 응용 프로그램 루트, system32에 있거나 GAC에로드되어있을 수도 있습니다.



답변

예. Assembly.LoadFrom어셈블리를 메모리에로드하는 데 사용해야 합니다. 그런 다음 Activator.CreateInstance원하는 유형의 인스턴스를 만드는 데 사용할 수 있습니다 . 리플렉션을 사용하여 먼저 유형을 찾아야합니다. 다음은 간단한 예입니다.

Assembly assembly = Assembly.LoadFrom("MyNice.dll");

Type type = assembly.GetType("MyType");

object instanceOfMyType = Activator.CreateInstance(type);

최신 정보

어셈블리 파일 이름과 유형 이름이 있으면 Activator.CreateInstance(assemblyName, typeName).NET 유형 확인을 요청하여 유형으로 해석 할 수 있습니다 . try / catch로이를 랩핑하여 실패한 경우 검색하지 않을 수있는 추가 어셈블리를 구체적으로 저장할 수있는 디렉토리 검색을 수행 할 수 있습니다. 이 시점에서 앞의 방법을 사용합니다.


답변

다른 Load*방법 의 한계를 고려하십시오 . 로부터 MSDN의 문서 …

LoadFile은 LoadFrom 메소드로 파일을로드 하지 않으며 LoadFrom 메소드와 같이로드 경로를 사용하여 종속성분석 하지 않습니다.

컨텍스트로드에 대한 자세한 내용은 LoadFrom문서를 참조하십시오.


답변

Activator.CreateInstance 가 작동해야합니다.

IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
                                                "TypeName" )
                               .Unwrap();

참고 : 유형 이름은 정규화 된 유형이어야합니다.

예:

var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);

foreach (object obj in aray)
{
    Console.WriteLine(obj);
}


답변

이 질문과 일부 답변이 매우 유용하다는 것을 알았지 만 경로 문제가 있었 으므로이 답변은 bin 디렉토리 경로를 찾아 라이브러리로드를 다루는 것입니다.

첫 번째 해결책 :

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);

두 번째 해결책

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");

다음과 같은 인터페이스에 대해 동일한 원칙을 사용할 수 있습니다 (클래스를 만들지 만 인터페이스로 캐스팅).

(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");

이 예는 웹 응용 프로그램을위한 것이지만 데스크톱 응용 프로그램에는 비슷한 것을 사용할 수 있습니다. 예를 들어 경로 만 다른 방식으로 해결됩니다.

Path.GetDirectoryName(Application.ExecutablePath)


답변

그것은 간단합니다.

MSDN의 예 :

public static void Main()
{
    // Use the file name to load the assembly into the current
    // application domain.
    Assembly a = Assembly.Load("example");
    // Get the type to use.
    Type myType = a.GetType("Example");
    // Get the method to call.
    MethodInfo myMethod = myType.GetMethod("MethodA");
    // Create an instance.
    object obj = Activator.CreateInstance(myType);
    // Execute the method.
    myMethod.Invoke(obj, null);
}

참조 링크는 다음과 같습니다

https://msdn.microsoft.com/en-us/library/25y1ya39.aspx


답변

Framework v4.5부터 Activator.CreateInstanceFrom () 을 사용 하여 어셈블리 내에서 클래스를 쉽게 인스턴스화 할 수 있습니다 . 다음 예제에서는이를 사용하는 방법과 매개 변수를 전달하고 리턴 값을 얻는 메소드를 호출하는 방법을 보여줍니다.

    // Assuming moduleFileName contains full or valid relative path to assembly    
    var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass");
    MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod");
    // Assuming the method returns a boolean and accepts a single string parameter
    bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));


답변

예. 지금 개인적으로 사용 가능한 예제가 없습니다. 나중에 일부를 찾으면 게시하겠습니다. 기본적으로 리플렉션을 사용하여 어셈블리를로드 한 다음 필요한 유형을 가져옵니다.

그 동안이 링크를 통해 시작하십시오.

런타임에 리플렉션을 사용하여 참조되지 않은 어셈블리로드