2011-07-09 21 views
10

Castle'ın Dinamik Proxy'sini kullanırken biraz (tuhaf olduğunu düşündüğüm) garip davranışlara rastladım. Aşağıdaki kod ileKale Dinamik Proxy, sınıfın içinden çağrıldığında yöntem çağrılarını engellemiyor

:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var c = new InterceptedClass(); 
     var i = new Interceptor(); 

     var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i); 

     cp.Method1(); 
     cp.Method2(); 

     Console.ReadLine(); 
    } 
} 

public class Interceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) 
    { 
     Console.WriteLine(string.Format("Intercepted call to: " + invocation.Method.Name)); 

     invocation.Proceed(); 
    } 
} 

public class InterceptedClass 
{ 
    public virtual void Method1() 
    { 
     Console.WriteLine("Called Method 1"); 
     Method2(); 
    } 

    public virtual void Method2() 
    { 
     Console.WriteLine("Called Method 2"); 
    } 
} 

ben çıkışını almak için bekliyordum:

  • Yakalayan çağrı için: Yöntemi1
  • Yöntem 1 Aranan
  • Yakalayan çağrı için: Method2
  • Yöntem 2
  • Intercepted çağrı için: 2

Ancak ne var Yöntem Aranan Method2

  • oldu:

    • Yakalayan çağrı için: Method1
    • Yöntem 1 Aranan
    • Yöntem 2 Aranan
    • Aşağıdaki çağrıya çağrılır: Yöntem2
    • Yöntem 2

    Anlatabildiğim kadarıyla, proxy yönteminin yalnızca proxy metodu çağrıları, aramanın Program2 den çağrıldıkça ancak InterceptedClass içinden değil, Method2'nin araya girmesi nedeniyle sınıfın dışından gelmesi durumunda gerçekleştirilebilir.

    Vekil olan sınıf içinde arama yaparken, artık vekilden geçmeyeceğini, ancak sadece bunun beklendiğini kontrol etmek istediğini ve eğer varsa, o zaman var olup olmadığını görmek isteyip istemediğinizi anlayabilirim. Aradıkları yerden bağımsız olarak aramalar kesiliyor mu?

    Teşekkür

  • cevap

    15

    DÜZENLEME: tl; dr - aşağıda açıklandığı gibi ben sadece farklı bir şekilde vekil oluşturma denedim, ve bunu peşindeydiler çıktı üretir. Sadece bu değiştirmek zorunda:

    var c = new InterceptedClass(); 
    var i = new Interceptor(); 
    
    var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i); 
    

    Bu Kime:

    var i = new Interceptor(); 
    var cp = new ProxyGenerator().CreateClassProxy<InterceptedClass>(i); 
    

    Anladığım kadarıyla

    , vekil jeneratör etkin bir şekilde sarıcı nesnesi yaratıyor. Bunlar iki ayrı nesne - biri sarmalayıcı katmanında engelleme vb. Ile etrafı saran bir sarıcıdır.

    O kendi yöntemini çağırır ile InterceptedClass örneği yaptıklarını nasıl değişebileceğini görmek zor:

    • DynamicProxy varolan nesne türünü değiştiremezsiniz; Bir nesne oluşturulduktan sonra, onun tür mevcut proxy oluşturma kullanılarak aracılığıyla ambalajı Method2aramak Method1 istiyorsanız
    • DynamicProxy varolan bir nesneye

    bağlıdırlar nasıl mevcut çağrılar değiştiremezsiniz sabittir kodu, sarıcı hakkında var olan nesneyi ya bir alan ya da bir yöntem parametresi olarak belirtmeniz gerekir. Alternatif olarak, başlangıç ​​nesnesinin oluşturulmasının farklı bir yolu olabilir; bu nedenle, proxy'si, bir anlamda hedef nesne için. Ben bunu, sorunlara neden olan hedef nesne tedarik olman şüpheli - Sana CreateClassProxy yerine CreateClassProxyWithTarget bakmak isteyebilirsiniz şüpheli. Gördüğünüz davranış açıkça "beklenen" olup olmadığı

    beklentilerinize bağlıdır - ama Kale Dinamik proxy :)

    +0

    Yep hakkında hiçbir şey bilmeden, ben ne beklenir kesinlikle var, ben tür çok düşündüm. Yani diğer terimlerle "cp" çağrıları kesişebilir ve "c" ye çağrı yapamaz ve "c" den "c" ye çağrıları içerir - ki bu hiç de şaşırtıcı değildir. Bir kenara göre: Soru sorduğumda biraz daha açıklayıcı değişken isimleri kullanmayı düşünmeliyim, ha? Güncelleme için –

    +0

    Teşekkür - CreateClassProxyWithTarget kullanarak nedeni gerçek problemde ben o zaman vekil sarmalamak istediğiniz bir IoC konteyner tarafından oluşturulan hedef nesne çözmeye çalışıyorum olmasıdır. Ancak bu sorun, bu sorunun kapsamı dışındadır. Yardım ettiğin için teşekkür ederim. –

    +0

    @George: Kale Dinamik Proxy'sini kullanmak için IoC konteynerini ikna etmenin herhangi bir yolu var mı? Söylediğin gibi, bu sorudan biraz ayrı, ama bu yapılabilir ... –

    İlgili konular