2012-11-08 8 views
2

문제를 해결하려면 약간 설명해야합니다. 프로젝트를 볼 수 있습니다C# 캡슐화 : 다른 프로젝트의 유형 가져 오기

프로젝트 1 프로젝트 2, 3

프로젝트 2를 볼 수 있습니다 3.

프로젝트 3은 DLL과 다른 앱입니다

나는 3 개 프로젝트가있다.

많은 하위 클래스가있는 클래스를 디자인해야했습니다. 하위 클래스에는 모두 기본에서 추상으로 선언 된 메서드가 있으므로 모두 사용해야합니다. 메소드의 코드가 프로젝트와 직접 상호 작용하기 때문에 모든 프로젝트에 배포해야합니다.

추상 기본 클래스가 프로젝트 3에, 서브 클래스는 2 년이며, 1 는 내가 가지고있는 문제가있다 :

public static IEnumerable<Type> GetSubClasses(Type typ) 
    { 
     IEnumerable<Type> subclasses = 
     from type in Assembly.GetAssembly(typ).GetTypes() 
     where type.IsSubclassOf(typ) && !type.IsAbstract 
     select type; 
     return subclasses; 
    } 

내가 노력하고있어 :

이 내가 쓴 방법은 형식의 모든 하위 클래스를 가져 오지만 내가 할 때 현재 프로젝트의 하위 클래스 만 가져옵니다. 예를 들어 project1에서 가져 오려고하면 프로젝트 2의 하위 클래스를 가져 오지 않습니다.

어떻게하면됩니까? 프로젝트 2에서 어셈블리 참조를 얻을 수 있지만 GetAssembly (Type t) 메서드가 없다는 것을 알았습니다. 모든 하위 클래스를 얻었습니다. 그것이 동일하면 나는 거기에서 같은 것을해야했다.

내 두 번째 질문은 더 쉬운 방법이 있습니까? 그것은 많은 프로젝트에서 그러한 클래스들을 가지고있는 "커다란"것이고 아마도 그것들을 하나에 넣는 해결책이있을 것입니다. 내가 말했듯이, 그들이 가지고 있어야하는 메소드의 코드는 자신이 속한 프로젝트와 직접 상호 작용해야합니다.

+1

프로젝트 4를 작성하고 거기에 하위 클래스를 추가하면이를 어떻게 귀하의 목록에 포함시킬 것입니까? – Jodrell

+1

이 함수의 목적은 무엇입니까? – Jodrell

+0

기본 클래스에 '추상'멤버가 필요한 것 같은데, 무엇을 달성하려고합니까? – Jodrell

답변

1

문제는 Assembly.GetTypes()입니다. 그것은 당신에게 그 특별한 어셈블리의 수업만을 제공합니다. 당신이 세 가지 어셈블리에 대한 Assembly 객체가있는 경우, 당신은 그래서 문제가 당신이 세 가지 Assembly 객체를 얻는 방법이다

assem1.GetTypes() 
.Concat(assem2.GetTypes()) 
.Concat(assem3.GetTypes()) 

처럼 뭔가를 할 수 있습니다. 프로젝트 1에서 말 할 수 있습니다.

var assem1 = typeof(SomeClassInProj1).Assembly; 
var assem2 = typeof(SomeClassInProj2).Assembly; 
var assem3 = typeof(SomeClassInProj3).Assembly; 

다른 어셈블리를 볼 수없는 프로젝트에서는로드해야합니다. Assembly.Load의 설명서를 참조하십시오.

+0

이 클래스는 좋게 보입니다. –

+0

고맙습니다. 하위 클래스가 있습니다. –

+0

@RobinBetka ,이 코드는 "Project 1"에서만 컴파일됩니다. – Jodrell

0

찾을 유형을 포함 할 수있는 모든 어셈블리를로드하고 유형을 찾아야합니다 당신이 루프에서하는 것처럼.

내가 그런 짓을 한 에 대한 몇 가지 기본 클래스에서 상속 현재의 응용 프로그램 bin 폴더에 어셈블리에서 모든 클래스의 목록을 얻을 :

// load all files from current dir which ends with `.dll` 
var q = from s in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll") 
     select s; 

var types = q.Select(s => getTypes(s, myBaseType)) 
      .SelectMany(typeList => typeList).ToList(); 

그리고 기능 getTypes :

IEnumerable<Type> getTypes(string filePath, Type baseType) { 
    Assembly a = Assembly.LoadFrom(filePath); 
    return a.GetTypes().Where(t => t.IsSubclassOf(baseType) && !t.IsAbstract); 
} 

.net 어셈블리가 아닌 폴더에 dll이 있으면 BadImageFormatException과 같은 몇 가지 예외를 처리해야합니다.

다른 방법은 검사 할 어셈블리 목록을 구성하는 것입니다.

0

모든 기본 클래스 또는 인터페이스는 해당 상속자 또는 구현자를 인식하거나 신경 써서는 안됩니다. 모든 상호 작용은 오버라이드 된 추상 또는 가상 멤버로 제한되어야합니다.

마찬가지로 공개 형식을 내보내는 어셈블리는 가져 오기 프로그램에 대해 알지 못합니다. "초기 바인딩"을 사용하면 순환 참조가 생성됩니다.

응용 프로그램 도메인에로드 된 모든 어셈블리를 concieveably 반영 할 수 있으며 어떤 유형에서 상속 받았는지 확인할 수 있지만이 정보로 무엇을 할 계획입니까? 아마도 더 간단하고 빠른 방법 일 것입니다.

+1

나는 그가 원한다고 생각하지 않는다. 기본 클래스가 그것에 대해 상속인을 알고 있다고 생각한다. 내 생각에 그는 자신의 앱에서 모든 상속인 목록을 동적으로 가져오고 싶어한다고 생각합니다. 예를 들어, 런타임에 설치된 모든 플러그인 목록 또는 이와 비슷한 내용. – Jan

+0

@Jan, 그러면 플러그인 유형을 정의하는 라이브러리가 아니라 플러그인을로드하는 애플리케이션의 함수가됩니다. – Jodrell

+0

네, OP가 * why *에 관한 질문에 대한 귀하의 의견에 답변해야한다고 생각합니다! – Jan