반사를 통해 생성 된 오브젝트를 올바르게 캐스팅하는 방법
-
09-06-2019 - |
문제
저는 반성에 대해 머리를 감 으려고해서 제가 작성하는 프로그램에 플러그인 기능을 추가하기로 결정했습니다. 개념을 이해하는 유일한 방법은 손가락을 더럽 히고 코드를 작성하는 것이므로 IPlugin 및 IHost 인터페이스로 구성된 간단한 인터페이스 라이브러리, IPlugin을 구현하는 클래스의 플러그인 구현 라이브러리 및 간단한 플러그인 개체로 간단한 작업을 수행하는 IHost 구현 클래스를 인스턴스화하는 콘솔 프로젝트.
반사를 사용하여 플러그인 구현 dll 내에 포함 된 유형을 반복하고 유형의 인스턴스를 만들고 싶었습니다. 이 코드로 성공적으로 클래스를 인스턴스화 할 수 있었지만 생성 된 객체를 인터페이스로 캐스팅 할 수 없었습니다.
이 코드를 시도했지만 예상대로 객체 o를 캐스팅 할 수 없습니다. 디버거로 프로세스를 밟았고 적절한 생성자가 호출되었습니다. Quickwatching 객체 o는 구현 클래스에서 볼 것으로 예상되는 필드와 속성이 있음을 보여주었습니다. 라코 디스
코드가 이것으로 작동하도록 만들었습니다. 라코 디스
제 질문은 다음과 같습니다.
- Activator.CreateInstance (Type t)가 개체를 반환하지만 개체가 구현 한 인터페이스로 개체를 캐스팅 할 수 없습니다. 왜?
- CreateInstance ()의 다른 오버로드를 사용해야하나요?
- 반성 관련 팁과 요령은 무엇인가요?
- 내가 얻지 못한 반성의 중요한 부분이 있습니까?
해결책
여기서 추측하고 있습니다. 코드에서 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 ()을 사용하여 문제에 대한 주요 해결책입니다.