2013-10-29 2 views
0

캐슬 다이나믹 프록시에 관한 질문이 있습니다. (캐슬 윈저를 오랫동안 IoC 프레임 워크로 사용해 왔지만 다이내믹 프록시를 직접 사용하지 않았습니다).캐슬 다이나믹 프록시로 메타 인터페이스 프록시하기

클래스의 기능을 설명하는 몇 가지 인터페이스가 있습니다. 예를 들어 :

public interface IBeatScissors 
{ 
    void BeatScissors(); 
} 

public interface IBeatRock 
{ 
    void BeatRock(); 
} 

public interface IBeatPaper 
{ 
    void BeatPaper(); 
} 

public interface IBeatSpock 
{ 
    void BeatSpock(); 
} 

public interface IBeatLizard 
{ 
    void BeatLizard(); 
} 

그리고 여기에 그들을 구현하는 클래스입니다 : 또한

public abstract class Rock : Weapon, IBeatScissors, IBeatLizard 
{ 
    public abstract void BeatScissors(); 
    public abstract void BeatLizard(); 
} 

public abstract class Paper : Weapon, IBeatRock, IBeatSpock 
{ 
    public abstract void BeatRock(); 
    public abstract void BeatSpock(); 
} 

public abstract class Scissors : Weapon, IBeatPaper, IBeatLizard 
{ 
    public abstract void BeatPaper(); 
    public abstract void BeatLizard(); 
} 

public abstract class Lizard : Weapon, IBeatPaper, IBeatSpock 
{ 
    public abstract void BeatPaper(); 
    public abstract void BeatSpock(); 
} 

public abstract class Spock : Weapon, IBeatScissors, IBeatRock 
{ 
    public abstract void BeatScissors(); 
    public abstract void BeatRock(); 
} 

, 나는 위의 기능을 결합 더 인터페이스가 (이 내가 "메타 인터페이스"로 참조 무엇인가)

public interface IBeatScissorsAndLizard : IBeatScissors, IBeatLizard 
{ 
} 

public interface IBeatRockAndSpock : IBeatRock, IBeatSpock 
{ 
} 

public interface IBeatPaperAndLizard : IBeatPaper, IBeatLizard 
{ 
} 

public interface IBeatPaperAndSpock : IBeatPaper, IBeatSpock 
{ 
} 

public interface IBeatScissorsAndRock : IBeatScissors, IBeatRock 
{ 
} 

는 지금은 "캐스팅"(또는 무엇이든)를 구현하는 클래스를 이러한 메타 인터페이스 및 소비하는 방법에 그들을에 전달하려는 :

제 실제 응용 프로그램에서 구현 가능한 클래스의 수가 너무 많기 때문에 구현 클래스에도 메타 인터페이스를 구현할 수 없습니다. 실제로 이것은 예제 일뿐입니다!

나는 꽤 많은 예를 들어, 내가 달성하기 위해 원하는 것을 "AlignToInterface"라는 확장 메서드가 과거에 Cs-Script을 사용하고있다 : 불행하게도

Rock rock = new Rock(); 
IBeatScissorsAndLizard beatem = rock.AlignToInterface<IBeatScissorsAndLizard>(); 

을, 여기이 때문에 사용할 수 없습니다 메타 인터페이스가 파생 된 메소드를 구현하지 않는다고 불평한다. 나는 이것이 버그라고 생각한다 - 인터페이스가 어떻게 다른 인터페이스를 구현할 수 있었 을까?!?!

지금 내 궁금한 점은 Castle Dynamic 프록시를 사용하여 비슷한 점이 있다면 어떻게 될까요?

도움을 주셨습니다.

업데이트 : 사용 예제를 편집했습니다.

답변

1

당신이 주장하면 성을 사용할 수 있습니다. 당신이 찾고있는 기능은 duck typing입니다. 기본 개념은 일부 인터페이스와 동일한 공개 API를 가진 클래스가 주어 지거나 인터페이스의 API가 클래스가 제공하는 API의 서브 세트 인 경우 인터페이스 참조를 통해이 클래스의 인스턴스를 사용할 수 있다는 것입니다.

Castle Windsor herehere으로이 기능을 구현하는 예를 찾을 수 있습니다. 내가 알고 있듯이이 두 가지 구현은 단지 개념 증명 일뿐입니다. 오리의 박스 입력을 지원하는 또 다른 DI 프레임 워크는 LinFu이지만 유지 관리가 오래되어 버린 것처럼 보입니다.

또 다른 질문은 오리 타이핑이 필요한지 아닌지입니다.

public abstract class Game 
{ 
    public abstract void BeatScissorsAndLizard<T>(T weapon) 
     where T : IBeatScissors, IBeatLizard; 

    public abstract void BeatPaperAndLizard<T>(T weapon) 
     where T : IBeatPaper, IBeatLizard; 

    //more here... 
} 

을 그리고 (주어진 수업 추상적하지 않습니다)처럼 사용 :

game.BeatPaperAndLizard(new Scissors()); 

//this does not compile: 
//game.BeatScissorsAndLizard(new Spock()); 

game.BeatScissorsAndLizard(new Rock()); 
사실 각 인터페이스의 구현을 가지고, 당신은 다음과 같은 방법으로 제네릭 형식 매개 변수 '제약 조건을 사용할 수를 감안할 때
+0

고마워요. @ galenus, 저에게 일해야합니다. 윈저를 IoC 프레임 워크로 사용하고 있기 때문에 캐슬 사용에 전념하고 싶습니다. 그래서 이미 캐슬이 있습니다. 코어 어셈블리가로드되었습니다.게시 한 첫 번째 예가 출발점으로 충분히 단순 해 보입니다. 나는 당신이 제공 한 대안을 사용할 수 없다. 왜냐하면 나는 범용 유틸리티 어셈블리에서이를 수행하고 있고, 내가 "더킹 (ducking)"하는 객체가 (아마도 타입 객체 일지라도) 외부로 전달되기 때문에 그것에 대한 통제권이 없다. 객체가 내부적으로 사용하고있는 모든 인터페이스를 구현하고 있는지 확인하고 싶습니다. – wexman

+0

형식 매개 변수 제약 조건을 사용하고 명시 적 인터페이스를 지정하는 것의 차이점은 무엇입니까? 제약 조건을 정의한 후에는 필요한 모든 인터페이스를 구현할 때까지 아무 것도 메서드에 들어갈 수 없습니다. 오리 타이핑의 경우 상당한 성능 비용을 가진 인스턴스도 * 오리 * 처리해야합니다. 사용자가 정의한 프레임 워크 유형을 "캐스팅 (casting)"하는 것과 같이 내부적으로 정의한 인터페이스로 외부에서 제공되는 일부 클래스를 마스크하려는 경우에 오리 (duck) 입력을 사용할 수 있습니다. – galenus

+0

예, 맞습니다.별로 의미가 없습니다. 더 현실적인 예를 편집했습니다. 무기는 실제로 외부에서 제공되므로 필요한 인터페이스를 구현할 수 있는지 확인할 수 없습니다. 어쨌든 감사합니다. 제공 한 솔루션으로 문제가 없습니다. – wexman