2010-05-02 2 views
0

NHibernate forumns에서이 질문을했지만이 질문이 더 일반적인 질문이라고 생각합니다. NHibernate는 프록시 생성기 (예 : Castle)를 사용하여 프록시를 생성합니다.동적 프록시 (예 : Castle, LinFu)의 기본 클래스 또는 기본 기능을 정의하십시오.

내가하고 싶은 것은 내 자신의 맞춤 동작 (예 : 비교 자)을 구현할 수 있도록 생성 된 프록시를 확장하는 것입니다. 다음과 같은 표준 .NET의 동작은 올바른 결과를 생산하지 못하기 때문에 나는이 필요합니다

//object AC is a concrete class 
collection.Contains(AC) = true 

//object AP is a proxy with the SAME id and therefore represents the same instance as concrete AC 
collection.Contains(AP) = false 

내 비교 자들은 AP에 의해 구현 된 경우 (예 : ID 경기를 할) 다음 collection.Contains (AP)가 I로, 진정한 반환 프록시가 암시 적이면 기대합니다. (NB : NH가 기본 클래스에서 상속 받았다고 말하면 그렇습니다. NH도 인터페이스에서 상속받을 수 있습니다.) -

나는 이것이 가능하다는 것을 전혀 확신하지 못합니다. 또는 시작 위치. NH가 사용하는 일반적인 프록시 생성기에서 수행 할 수있는 것입니까?

답변

0

행동 이런 종류의 LinFu.DynamicProxy 가능합니다,하지만 당신은 원래 인터셉터로 다시 호출을 위임 사용자 정의 인터셉터와 NHibernate에 의해 제공되는 인터셉터 교체해야 할 것입니다 :

var yourProxiedInterfaceInstance = ... 

// Get the Interceptor that NHibernate uses 

var proxy = (IProxy)yourProxiedInterfaceInstance; 

var interceptor = proxy.Interceptor; 

// You'll need to create a decorator class around the IInterceptor interface 
var yourInterceptor = new SomeCustomInterceptor(interceptor); 

// Replace the interceptor here 
proxy.Interceptor = yourInterceptor; 

이것은이다 LinFu가 생성하는 모든 프록시 인스턴스는 인터셉터를 필요로하기 때문에 LinFu와는 꽤 쉽습니다. 인터셉터를 변경하면 자동으로 프록시 동작을 변경할 수 있습니다. 도움이되기를 바랍니다.

+0

감사를 설정하는 것입니다. 적어도 지금 내가 원하는 것은 벽에서 완전히 벗어난 것이 아닙니다. LinFu를 살펴 보겠습니다. – GrahamB

2

Castle DynamicProxy에서는 몇 가지 선택 사항이 있습니다.

먼저 프록시를 만들 때 additionalInterfacesToProxy 중 하나로 IComparer<T>을 제공합니다. 인터페이스는 진행할 실제 구현이 없으므로 Proceed을 호출하는 대신 메소드에 대한 실제 논리를 제공하는 인터셉터를 제공해야합니다.

또는 인터페이스를 구현하고 필요한 로직을 제공하는 믹스 인을 제공 할 수 있습니다. mixin 레퍼런스를 프록시 나 그 타겟으로 다시 전달할 필요가있을 것입니다. 전용 인터페이스 프록시를 사용할 수

세 번째 옵션은 기본 클래스에게 팁을위한 proxyGenerationOptions.BaseClassForInterfaceProxy = typeof(SomethingImplementingComparer);

+0

크 르지 스토프 (Krzysztof), 세 번째 옵션 - 성 설정이라고 가정합니다. 어디서나 NH 설명서에서 찾을 수 없습니다. 제대로 연결하면 가장 쉬운 옵션 인 것 같습니다. 아직 성 안에 NH 성을 구성하는 방법이 확실하지 않습니다! – GrahamB

+0

예, 성의 설정 중 일부입니다. NHibernate를 연결하기 위해서는 자신 만의'ProxyFactoryFactory'와'ProxyFactory'를 제공해야한다고 생각합니다. 나는'NHibernate.Bytecode.Castle.dll'에있는 것을 보면서 시작하겠다. –

+0

Krzysztof는 세 번째 옵션을 시도했지만 예상대로 작동하지 않는다. 성에 의해 생성 된 프록시는 실제로 내가 지정한 기본 클래스로 캐스트되지만, 기본 클래스에 프록시를 캐스트하지 않는 한 기본 클래스 비교자를 시작하지 않습니다. Castle은 기본 클래스를 인터페이스의 프록시로 사용하지 않고 기본 클래스를 "프록 싱"하는 것처럼 보입니다. 이 올바른지? – GrahamB