2010-11-18 3 views
2

아래와 같이 ICatBase 및 ICatExtension에서 파생 된 인터페이스 ICat가 있다고 가정합니다. 두 개의 서로 다른 인터페이스의 경우 구현이 가능합니다 (CatBase 및 CatExtension). Castle의 DynamicProxy를 사용하여 ICat의 인스턴스로 병합 할 수 있습니까?DynamicProxy를 사용하여 여러 클래스가있는 여러 인터페이스를 병합하려면 어떻게해야합니까?

ICatExtension이 CatExtension에 의해 구현되고 ICatBase가 인터셉터에 의해 '구현'된 프록시를 만들 수 있습니까? 어떻게이 일을 성취 할 수 있습니까?

public interface ICatBase 
{ 
    string Name { get; set; } 
    int Age { get; set; } 
} 

public interface ICatExtension 
{ 
    string Description { get; } 
} 

public interface ICat : ICatBase, ICatExtension 
{ 
} 

public class CatBase : ICatBase 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

public class CatExtension : ICatExtension 
{ 
    public string Description 
    { 
     get { return "Furry"; } 
    } 
} 

내가이 일을하기 위해 유지 mixin을 사용하는 것을 시도하고있다

편집,하지만 NotImplementedException 결과 아래의 코드.

var generator = new ProxyGenerator(); 
var options = new ProxyGenerationOptions(); 
options.AddMixinInstance(new CatBase()); 
options.AddMixinInstance(new CatExtension()); 
var cat = generator.CreateInterfaceProxyWithoutTarget<ICat>(options);   
cat.Name = "Joey"; 

가 DynamicProxy2 에러이다 방법에 지정된 어떤 인터셉터가 없습니다 '무효 SET_NAME (선택 System.String)'에는 대상이 없다. 대상이없는 메소드를 호출 할 때 '진행'할 구현이 없으며 구현을 모방하는 인터셉터의 책임입니다 (반환 값, 인수 등 설정)

호출 및 디스패치를 ​​가로채는 사용자 정의 인터셉터를 만들 수 있습니다 올바른 인터페이스로 이동해야하지만 더 쉽고/더 나은 방법이 있어야한다고 생각합니다. 나 맞아?

편집 # 2

는 르지을 주셔서 감사합니다! 아래 줄을 사용하는 것이 해결책이었습니다.

var generator = new ProxyGenerator(); 
var options = new ProxyGenerationOptions(); 
options.AddMixinInstance(new CatBase()); 
options.AddMixinInstance(new CatExtension()); 

var cat = (ICat)generator.CreateClassProxyWithTarget(typeof(object), new[] { typeof(ICat)}, new object(), options); 

EDIT # 3

최종 단계로서,이 예에서 프록시를 생성하는 윈드 용기를 구성 하였다. 이 작업을 수행 할 수 있었던 유일한 방법은 나중에 이름을 지정하고 나중에 ICat 인터페이스에 캐스팅하여 System.Object의 인스턴스를 확인하고 "Cat"이라는 이름을 지정하는 것이 었습니다.

WindsorContainer container = new WindsorContainer(); 
container.Register(
    Castle.MicroKernel.Registration.Component.For<object>(). 
     Named("Cat"). 
     Proxy.AdditionalInterfaces(typeof (ICat)). 
     Proxy.MixIns(new CatBase()). 
     Proxy.MixIns(new CatExtension()) 
    ); 

var cat = (ICat)container.Resolve(typeof(object), "Cat"); 

난 그냥 특정 이름을 참조하지 않고, ICAT 인스턴스의 컨테이너를 요청할 수있는이에 더 우아한 방법이 있나요?

+0

아무데도 아직 문서화되어 있는지 기억이 나지 않지만 올바른 동작을 볼 수 있습니다. 타겟이없는'ICat'는 믹스 인보다 우선합니다. 그것이 어떻게 작동하는지보십시오 : http://issues.castleproject.org/issue/DYNPROXY-96 –

+0

좋아요, 그래서 완전한 인터페이스 인'ICat'는 타겟이나 믹스 인 중 하나에 의해 구현되어 있어야합니다. 하지만 실제로 두 개의 인터페이스를 병합하는 것을 금지하지는 않습니까? 구현의 일부 (ICatBase)가 하나의 target/mixin에 전달되고 다른 하나 (ICatExtension)가 (ICatBase와 ICatExtension으로) 파견되는 'ICat' 인스턴스를 얻고 싶습니다. 또 다른 인스턴스. 보다 구체적으로, 우리는'ICatExtension'에 대한 구현을 제공하고'ICatBase'는 인터셉터로 자동 생성되어야합니다. – Ringo

+0

아니요, 이것은 목표가 믹스 인보다 우선한다는 것을 의미합니다. 이 인터페이스를 목표로 삼지 마십시오. 'System.Object'에 대한 클래스 프록시를 생성하고이 인터페이스를 프록시에 추가 인터페이스로 던지십시오. 이렇게하면 우선 순위가 가장 낮아지고 호출이 mixins로 바뀝니다. –

답변

1

믹스는 일반적으로 그 용도로 사용됩니다.

+0

포인터 주셔서 감사.내 게시물을 편집했으며 실제로 몇 가지 지침을 사용할 수 있습니다. – Ringo

관련 문제