2010-06-03 12 views
10

मुझे ProxyGenerator.CreateInterfaceProxyWithTarget पर इसका उदाहरण प्रदान करके एक इंटरफ़ेस प्रॉक्सी करने के लिए कैसल डायनैमिक प्रॉक्सी का उपयोग करने की आवश्यकता है। मुझे यह भी सुनिश्चित करने की ज़रूरत है कि बराबर कॉल, गेटहाशकोड और टूस्ट्रिंग ठोस उदाहरण पर विधियों को हिट करता है, कि मैं गुजर रहा हूं, और मैं इसे काम नहीं कर सकता।कैसल डायनामिक प्रॉक्सी: इंटरफ़ेस को प्रॉक्सी करने पर प्रॉक्सी को बराबर कैसे करें?

using System; 
using Castle.Core.Interceptor; 
using Castle.DynamicProxy; 

public interface IDummy 
{ 
    string Name { get; set; } 
} 

class Dummy : IDummy 
{ 
    public string Name { get; set; } 

    public bool Equals(IDummy other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return Equals(other.Name, Name); 
    } 

    public override bool Equals(object obj) 
    { 
     return Equals(obj as IDummy); 
    }  
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var g = new ProxyGenerator(); 
     IDummy first = new Dummy() {Name = "Name"}; 
     IDummy second = new Dummy() {Name = "Name"}; 
     IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, new ConsoleLoggerInterceptor()); 
     IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, new ConsoleLoggerInterceptor()); 

     Console.WriteLine(first.Equals(second));   
     Console.WriteLine(firstProxy.Equals(secondProxy)); 
    } 
} 

internal class ConsoleLoggerInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) 
    { 
     Console.WriteLine("Invoked " + invocation.Method.Name); 
    } 
} 

DynamicProxy के साथ इस संभव है:

दूसरे शब्दों में, मैं इस छोटा सा नमूना दो बार True मुद्रित करने के लिए है, जबकि वास्तव में यह True,False प्रिंट करना चाहते हैं? कैसे ?

+0

आप किस संस्करण का उपयोग कर रहे हैं? –

+0

मैं स्पष्टीकरण के लिए धन्यवाद DynamicProxy2 2.1.1 – driis

उत्तर

12

यह थोड़ा मुश्किल है। Proxies कैसे काम करते हैं Take a look at documentation। इंटरफ़ेस प्रॉक्सी किसी ऑब्जेक्ट को लपेटती है और निर्दिष्ट इंटरफ़ेस को इंटरसेप्ट कॉल करती है। चूंकि Equals उस इंटरफ़ेस का हिस्सा नहीं है, तो बराबर के लिए दूसरी कॉल प्रॉक्सी की तुलना कर रही है, न कि उनके लक्ष्य।

तो दूसरे Equals कॉल के लिए कार्यान्वयन क्या प्रदान करता है?

प्रॉक्सी सिर्फ IDummy इंटरफ़ेस को लागू करने वाला एक और वर्ग है। किसी भी वर्ग के रूप में इसके पास बेस क्लास भी है, और यह Equals का आधार कार्यान्वयन है जो लागू हो जाता है। यह बेस क्लास डिफ़ॉल्ट रूप से System.Object

मुझे आशा है कि अब आप देखेंगे कि यह कहां जा रहा है। इस समस्या का समाधान कुछ प्रॉक्सी जागरूक बेस क्लास को लागू करने के लिए प्रॉक्सी को बताना है जो कॉल को प्रॉक्सी लक्ष्य पर अग्रेषित करेगा। इसके कार्यान्वयन के भाग इस प्रकार दिखाई देंगे:

public class ProxyBase 
{ 
    public override bool Equals(object obj) 
    { 
     var proxy = this as IProxyTargetAccessor; 
     if (proxy == null) 
     { 
      return base.Equals(obj); 
     } 
     var target = proxy.DynProxyGetTarget(); 
     if (target == null) 
     { 
      return base.Equals(obj); 
     } 
     return target.Equals(obj); 
    } 
    // same for GetHashCode 
} 

अब आप केवल अपने इंटरफेस प्रॉक्सी के लिए इस आधार वर्ग का उपयोग करने के लिए प्रॉक्सी जनरेटर निर्देश देने के लिए, डिफ़ॉल्ट के बजाय जरूरत है।

var o = new ProxyGenerationOptions(); 
o.BaseTypeForInterfaceProxy = typeof(ProxyBase); 
IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, o); 
IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, o); 
+0

का उपयोग कर रहा हूं। मुझे लगा कि यह ऐसा कुछ था, इंटरफ़ेस बराबर विधियों को परिभाषित नहीं कर रहा था। मैं आपके सुझाव का प्रयास करूंगा :-) – driis

+1

यह एक आकर्षण की तरह काम करता है :-) – driis

0

आपके नमूने में; आपकी कक्षा Dummy लागू IDummy, लेकिन Equals का एक और अधिक विशिष्ट ओवरराइड प्रदान करता है।

public interface IDummy : IEquatable<IDummy> 
{ 
    string Name { get; set; } 
} 

इस तरह, आपके इंटरफेस अब अधिक विशिष्ट Equals ओवरराइड, जो आपके उत्पन्न प्रॉक्सी होगा प्रॉक्सी कॉल का मतलब है में शामिल हैं: करज़िस्तोफ के सुझाव के लिए एक वैकल्पिक इस विधि उदाहरण के लिए, यह IEquatable<T> लागू होने से अपने इंटरफेस में खींचने के लिए है आवश्यकतानुसार अपने लक्ष्य के लिए।

स्पष्ट रूप से यह पूरी समस्या का समाधान नहीं करता है और केवल आपकी प्रॉक्सी को Equals(IDummy) पर कॉल अग्रेषित करने की अनुमति देगा और Equals(object) (या GetHashCode उस मामले के लिए) नहीं देगा।

संबंधित मुद्दे