2012-05-24 4 views
8

나는 예를 가지고있다Activator.CreateInstance를 인터페이스와 함께 사용할 수 있습니까?

 Assembly asm = Assembly.Load("ClassLibrary1"); 
     Type ob = asm.GetType("ClassLibrary1.UserControl1"); 
     UserControl uc = (UserControl)Activator.CreateInstance(ob); 
     grd.Children.Add(uc); 

내가 클래스의 인스턴스를 만드는거야,하지만 어떻게 어떤 인터페이스를 구현하는 클래스의 인스턴스를 만들 수 있습니까? 즉 UserControl1ILoad 인터페이스를 구현합니다.

U : 개체를 나중에 인터페이스 할 수 있지만 어셈블리의 어떤 유형이 인터페이스를 구현하는지 알 수 없습니다.

+6

; 인터페이스를 구현하는 클래스를 생성하여 인터페이스로 전달할 수 있습니다. – Marco

+1

ILoad 유형의 객체를 인스턴스화 할 수 없습니다. 인터페이스입니다. – JustinDanielson

답변

14

이것은 몇 차례 사용한 코드입니다.

Type[] iLoadTypes = (from t in Assembly.Load("ClassLibrary1").GetExportedTypes() 
        where !t.IsInterface && !t.IsAbstract 
        where typeof(ILoad).IsAssignableFrom(t) 
        select t).ToArray(); 

는 그런 다음 ILoad 구현으로 ClassLibrary1의 모든 유형이 : 그것은 특정 인터페이스를 구현하는 어셈블리의 모든 유형을 찾습니다.

당신은 그들 모두를 인스턴스화 수 : 라이브러리가 프로젝트에서 참조하는 경우

ILoad[] instantiatedTypes = 
    iLoadTypes.Select(t => (ILoad)Activator.CreateInstance(t)).ToArray(); 
+0

감사합니다. –

+0

다음 오류가 발생합니다. '소스 유형'System.Reflection.Assembly '에 대한 쿼리 패턴 구현을 찾을 수 없습니다. '찾을 수없는 곳.' – dotNET

+1

발견. 위의 코드에서'Load ("ClassLibrary1")'뒤에'.GetExportedTypes();가 와야합니다. – dotNET

4

당신이 작성하는 경우 또한, 당신은 인터페이스를 통해 취급 할 필요가 없습니다 당신은 인터페이스의 인스턴스를 만들 수 있지만,

UserControl1 implements ILoad inteface

경우 ILoad

ILoad uc = (ILoad)Activator.CreateInstance(ob); 
grd.Children.Add(uc); 

으로 결과 객체를 사용할 수 있습니다

UserControl1 uc = (UserControl1)Activator.CreateInstance(ob); 
grd.Children.Add(uc); 

회원은 ILoad입니다. 로 표기 됨 uc.SomeILoadMethod();

+0

'ob'은 여전히 ​​인터페이스를 나타내는 것이 아니라 클래스를 나타내는 타입입니다. – Guillaume

+0

@Guillaume 생성 된 객체가 ILoad를 구현하므로 직접 사용할 수 있습니다. – archil

+0

좋아요,하지만 ILoad **를 구현하는 어셈블리에서 어떻게 타입을 찾을 수 있습니까? –

3

인터페이스는 인터페이스입니다. 그것은 템플릿입니다. 인터페이스를 인스턴스화하려는 이유는 무엇입니까? 인터페이스를 구현하고 해당 클래스를 인스턴스화합니다. 인터페이스를 인스턴스화 할 수는 없지만 실제로는 이해가되지 않습니다.

+1

물론 인터페이스를 쉽게 구현할 수있는 방법이 있습니다. DTO를 상상해보십시오. 행동없는 포코. 모의 프레임 워크에서 쉽게 사용할 수 있도록 인터페이스로 만들려고하지만 인터페이스를 구현할 때 기본적으로 유지해야하는 두 개의 코드 조각이 있습니다. NServiceBus와 같은 일부 프레임 워크에서는 "인터페이스를 인스턴스화"할 수 있습니다. Activator와 같은 기능을 통해 쉽게 수행 할 수 있다고 말하는 것이 아닙니다. "이해가되지 않습니다."라고 말하면서도이 기능을 사용할 수 없습니다. – Morten

4

원하는 것은 'NInject'와 같은 IoC 컨테이너를 사용하여 얻을 수 있습니다. 인터페이스를 요청한 경우 구체 유형을 반환하도록 컨테이너를 구성 할 수 있습니다.

2

당신이 사용할 수 있습니다 :

static public IEnumerable<Type> GetTypesFromLibrary<T>(String library) 
    { 
     var MyAsemblies = AppDomain.CurrentDomain.GetAssemblies() 
         .Where(a=>a.GetName().Name.Equals(library)) 
         .Select(a=>a); 
     var Exported = MyAsemblies 
         .FirstOrDefault() 
         .GetExportedTypes(); 
     var Asignable = Exported 
         .Where (t=> !t.IsInterface && !t.IsAbstract 
         && typeof(T).IsAssignableFrom(t)) 
         .Select(t=>t) 
         .AsEnumerable(); 
     return Asignable; 
    } 

    static public T GetInstanceOf<T>(String library, String FullClassName) 
    { 
     Type Type = GetTypesFromLibrary<T>(library) 
         .Where(t => t.FullName.Equals(FullClassName)) 
         .FirstOrDefault(); 
     if (Type != null) 
     { 
      T Instance = (T)Activator.CreateInstance(Type); 
      return Instance; 
     } 
     return default(T); 
    } 
2

허용 대답 유일한 문제는 당신이해야한다는 것입니다 인터페이스를 구현하는 어셈블리의 구체적인 클래스입니다.

런타임시 동적 객체를 만들고 원하는 인터페이스를 구현할 수있는 CustomActivator를 작성하지 않도록하십시오. https://github.com/fabriciorissetto/CustomActivator

통화가 간단하다 :

은 내가 GitHub의에 넣어 당신은 인터페이스의 인스턴스를 만들 수 없습니다

CustomActivator.CreateInstance<MyInterface>(); 
관련 문제