반사를 통해 생성 된 오브젝트를 올바르게 캐스팅하는 방법

StackOverflow https://stackoverflow.com/questions/31567

  •  09-06-2019
  •  | 
  •  

문제

저는 반성에 대해 머리를 감 으려고해서 제가 작성하는 프로그램에 플러그인 기능을 추가하기로 결정했습니다. 개념을 이해하는 유일한 방법은 손가락을 더럽 히고 코드를 작성하는 것이므로 IPlugin 및 IHost 인터페이스로 구성된 간단한 인터페이스 라이브러리, IPlugin을 구현하는 클래스의 플러그인 구현 라이브러리 및 간단한 플러그인 개체로 간단한 작업을 수행하는 IHost 구현 클래스를 인스턴스화하는 콘솔 프로젝트.

반사를 사용하여 플러그인 구현 dll 내에 포함 된 유형을 반복하고 유형의 인스턴스를 만들고 싶었습니다. 이 코드로 성공적으로 클래스를 인스턴스화 할 수 있었지만 생성 된 객체를 인터페이스로 캐스팅 할 수 없었습니다.

이 코드를 시도했지만 예상대로 객체 o를 캐스팅 할 수 없습니다. 디버거로 프로세스를 밟았고 적절한 생성자가 호출되었습니다. Quickwatching 객체 o는 구현 클래스에서 볼 것으로 예상되는 필드와 속성이 있음을 보여주었습니다. 라코 디스

코드가 이것으로 작동하도록 만들었습니다. 라코 디스

제 질문은 다음과 같습니다.

  1. Activator.CreateInstance (Type t)가 개체를 반환하지만 개체가 구현 한 인터페이스로 개체를 캐스팅 할 수 없습니다. 왜?
  2. CreateInstance ()의 다른 오버로드를 사용해야하나요?
  3. 반성 관련 팁과 요령은 무엇인가요?
  4. 내가 얻지 못한 반성의 중요한 부분이 있습니까?
도움이 되었습니까?

해결책

여기서 추측하고 있습니다. 코드에서 IPlugin 인터페이스의 정의가 어디에 있는지 명확하지 않지만 호스트 응용 프로그램에서 캐스트 할 수없는 경우 호스트 어셈블리에 IPlugin 인터페이스가있는 것입니다.플러그인 어셈블리에서 동시에.작동하지 않습니다.

가장 쉬운 방법은 호스트 어셈블리에서 IPlugin 인터페이스를 공용으로 표시 한 다음 플러그인 어셈블리가 참조 호스트 애플리케이션 어셈블리 를 갖도록하는 것입니다. 그러면 두 어셈블리 모두 에 액세스 할 수 있습니다.동일한 인터페이스 .

다른 팁

hmmm ... Assembly.LoadFrom을 사용하여 어셈블리를로드하는 경우 Assembly.LoadFile을 대신 변경해보십시오.

저를 위해 일했습니다

여기에서 : http : //www.eggheadcafe.com / community / aspnet / 2 / 10036776 / solution-found.aspx

@ 루 보스 하 스코

코에 못 박았습니다.내 원래 디자인에는 플러그인 인터페이스 어셈블리를 참조하는 호스트 및 플러그인 구현이있는 세 가지 다른 어셈블리가 있습니다.

호스트 구현 및 인터페이스 어셈블리와 플러그인 구현 어셈블리로 별도의 솔루션을 시도했습니다.해당 솔루션 내에서 첫 번째 블록의 코드는 예상대로 작동했습니다.

공통 어셈블리를 참조하는 두 어셈블리가 공통 어셈블리에서 동일한 유형을 얻지 못하는 이유를 잘 이해하지 못하기 때문에 생각할 시간이 조금 더 주어졌습니다.

이 문제를 직접 해결하려고했지만 답을 찾았습니다!

3 개의 서로 다른 C # 프로젝트가 있습니다.

  • A-플러그인 인터페이스 프로젝트
  • B-호스트 exe 프로젝트-> 참조 A
  • C-플러그인 구현 프로젝트-> 참조 A

    내가 캐스트하려는 네임 스페이스와 일치하도록 플러그인 인터페이스 프로젝트의 어셈블리 이름을 변경할 때까지 캐스팅 오류가 발생했습니다.

    예 : 라코 디스

    IPluginModule 인터페이스가 정의 된 어셈블리가 'Common'이라고했기 때문에 실패했습니다. 그러나 내가 캐스팅 한 -type-은 'Blah.Plugins.Common.IPluginModule'이었습니다.

    인터페이스 proj의 어셈블리 이름을 'Blah.Plugins.Common'으로 변경하여 캐스트가 성공했음을 의미합니다.

    이 설명이 누군가에게 도움이되기를 바랍니다.코드로 돌아 가기 ..

당신의 유형이 공개되지 않았나요? 그렇다면 부울을받는 오버로드를 호출하세요 : 라코 디스

또한 첫 번째 예에서 o가 null인지 확인하고 그렇지 않은 경우 o.GetType (). Name을 출력하여 실제 값을 확인합니다.

@ 해킹 됨

나는 의사 코드를 단순하게 유지하려고 노력했습니다.foreach는 많은 공간과 중괄호를 차지합니다.명확히했습니다.

o.GetType (). FullName은 예상되는 객체 인 Plugins.Multiply를 반환합니다.Plugins.Multiply는 IPlugin을 구현합니다.나는 저녁을 포기할 때까지 디버거에서 프로세스를 꽤 많이 밟았다.전체 엉망이 될 때까지 생성자 화재를 보았 기 때문에 캐스팅하지 못한 이유를 알 수 없었습니다.오늘 저녁에 돌아와서 작동했지만 첫 번째 코드 블록에서 캐스트가 실패한 이유를 여전히 이해하지 못합니다.두 번째 코드 블록은 작동하지만 기분이 나쁩니다.

위의 egghead에 대한 링크는 .LoadFrom () 대신 Assembly.LoadFile ()을 사용하여 문제에 대한 주요 해결책입니다.

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