2010-11-11 15 views
7

मैं एसएल v2.5.1.0 के लिए कैसल विंडसर का उपयोग कर रहा हूं। मेरे पास यह प्रॉक्सी आंतरिक वर्ग है (इंटरफेस निश्चित रूप से सार्वजनिक हैं, लेकिन कार्यान्वयन आंतरिक है, ताकि उपभोक्ता केवल इंटरफ़ेस से अवगत हो)।कैसल विंडसर आंतरिक दृश्य सिल्वरलाइट

मैं .NET 4.0 कैसल विधानसभाओं के साथ आंतरिक कक्षाएं

[assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")] 
[assembly: InternalsVisibleTo("Castle.Windsor, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")] 
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 

पूर्ण .NET 4.0 मोड में, के साथ अपने विधानसभा में निम्न विशेषताओं का उपयोग कर रहा है, इस ठीक काम करता है और मेरे प्रकार ठीक प्रॉक्सी कर रहे हैं। सिल्वरलाइट में, सिल्वरलाइट कैसल विधानसभाओं के साथ, मैं मिलता है:

Type ConsoleApplication4.MyTypeToBeProxied is not public. Can not create proxy for types that are not accessible. 

इसके अलावा, बस समस्या निवारण करते समय, जोड़ने में निम्नलिखित कोई फर्क लगता है ...:

[assembly: InternalsVisibleTo("System.Core, PublicKey=00000000000000000400000000000000")] 
[assembly: InternalsVisibleTo("System.Core, PublicKey=" + 
"00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649" + 
"383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb7" + 
"7e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638" + 
"fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c" + 
"123b37ab")] 

और मैंने रनटाइम पर भी सत्यापित किया गया है कि एसएल में गतिशील रूप से होस्ट की गई असेंबली का नाम अभी भी डायनामिकप्रॉक्सिजेनएस्परब्स 2 है।

कोई विचार? धन्यवाद।

संपादित:

मैं इस समस्या मुझे लगता है कि पाया: .NET 4.0 के लिए

कैसल है:

private bool IsAccessible(Type target) 
{ 
    //  .... 
    return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy); 

} 
DefaultProxyBuilder में

... और SL 4

है
private bool IsAccessible(Type target) 
{ 
    target.IsNested(); 
    return (target.IsPublic || target.IsNestedPublic); 
} 

क्या यह कुछ है जो सी में तय किया जा सकता है अस्थिर स्रोत? या क्या मुझे डिफॉल्टप्रोक्सी फैक्ट्री को उप-श्रेणी की आवश्यकता है?

उत्तर

2

मुझे इसके साथ कुछ भाग्य था। ईमानदार होने के लिए, मुझे यकीन नहीं है कि क्यों, लेकिन मैं Krzysztof द्वारा वर्णित समस्या को पुन: पेश नहीं कर सका। मुझे संदेह है ... हो सकता है ... इस तथ्य के साथ कुछ करने के लिए कुछ है कि मेरी असेंबली एसएनएड हैं ... जिसके लिए मुझे एक अतिरिक्त बदलाव करने की आवश्यकता है ... लेकिन एक बार मैंने किया, मैं प्रॉक्सी हल करने में सक्षम था एक एसएल परीक्षण आवेदन में आंतरिक कक्षाओं (सार्वजनिक इंटरफेस के साथ) के लिए।

एकमात्र परिवर्तन मुझे कैसल में बनाना था। मुख्य स्रोत फ़ील्ड बनाने के लिए ModuleScope.moduleBuilder और ModuleScope.moduleBuilderWithStrongName निजी के बजाय संरक्षित था।लेकिन फिर, यह केवल जरूरी था ताकि मैं एसएल में एक एसएनएड गतिशील असेंबली को परिभाषित कर सकूं, जिसे कैसल में मॉड्यूलस्कोप द्वारा एसएल के लिए अक्षम किया गया है। कोर।

private class StrongNameModuleScope : ModuleScope 
    { 
     public StrongNameModuleScope() 
     { 
      var assemblyName = new AssemblyName("DynamicProxyGenAssembly2"); 
      // copied from another one of my SN assemblies (plus GetName() on assembly is security critical so I can't pull it off the executing assembly) 
      byte[] publicKey = Convert.FromBase64String(@"ACQAAASAAACUAAAABgIAAAAkAABSU0ExAAQAAAEAAQBvwWquPXQG9zfemS8uDsFdGDScOCSjZ9aFsQDtrrAqKzvlxEGMz3t9Q9M3X9NKqy1ouLZi+sX8yVDafX+UnygFWWfOBosw9nGwG61MTKEhEjdKH0rECahGIXY+ETdNY64HduuH/BIbEs/RDhrrH2hiqGrOGb6AghD1sZ6g0A1qkg=="); 
      assemblyName.SetPublicKey(publicKey); 
      AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); 
      ModuleBuilder module = assembly.DefineDynamicModule("DynamicProxyGenAssembly2"); 
      moduleBuilder = module; 
      moduleBuilderWithStrongName = module; 
     } 
    } 

और एक कस्टम DefaultProxyBuilder:

/// <summary> 
    /// A custom IProxyBuilder copies from the full .NET Castle implementation that allows for proxies of internal types where the InternalsVisibleToAttribute is applied. 
    /// </summary> 
    private class DefaultProxyBuilder : IProxyBuilder 
    { 
     ... 
     // Methods 
     public DefaultProxyBuilder() 
      : this(new StrongNameModuleScope()) 
     { 
     } 
     ... 
     private static bool IsAccessible(Type target) 
     { 
      bool isTargetNested = target.IsNested; 
      bool isNestedAndInternal = isTargetNested && (target.IsNestedAssembly || target.IsNestedFamORAssem); 
      bool internalAndVisibleToDynProxy = ((!target.IsVisible && !isTargetNested) || isNestedAndInternal) && InternalsHelper.IsInternalToDynamicProxy(target.Assembly); 
      return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy); 
     } 
    } 

और एक कस्टम DefaultProxyFactory:

/// <summary> 
    /// A simple DefaultProxyFactory to wrap the modified DefaultProxyBuilder. 
    /// </summary> 
    private class DefaultProxyFactory : global::Castle.Windsor.Proxy.DefaultProxyFactory 
    { 
     public DefaultProxyFactory() 
     { 
      generator = new ProxyGenerator(new DefaultProxyBuilder()); 
     } 
    } 

और कंटेनर सेटअप:

तो, अब मैं एक कस्टम ModuleScope इस प्रकार है
 container = new WindsorContainer(); 

     container.Kernel.ProxyFactory = new DefaultProxyFactory(); 

मुझे कैसल को संशोधित करने के बहुत शौकीन नहीं हैं। अधिक स्रोत, इसलिए मैं वास्तव में अपने विचारों को Krzysztof सुनना चाहूंगा ... हो सकता है कि आप केवल उन क्षेत्रों को संरक्षित कर सकें यदि यह समाधान अन्य परीक्षणों के लिए काम नहीं करता है मामलों?

+0

हम्म दिलचस्प - इसलिए मुझे लगता है कि यहां महत्वपूर्ण अंतर यह हो सकता है कि आप जेनरेटेड असेंबली को अपने स्वयं के असेंबली के समान कुंजी के साथ साइन करें, जबकि आम तौर पर यदि डीपी दृढ़ता से नामित असेंबली उत्पन्न करता है तो इसे कैसल की कुंजी के साथ हस्ताक्षरित किया जाता है। तो मैं ** अनुमान लगा रहा हूं ** शायद नियम यह है कि आप एस्सेबली बी में असेंबली ए से आंतरिक प्रकार का उपयोग कर सकते हैं यदि ए के पास मित्र के रूप में बी है और दोनों एक ही कुंजी के साथ हस्ताक्षरित हैं। –

+0

इसकी जांच के लिए धन्यवाद - इसे जारी करने वाले ट्रैकर में रखें और हम इसे vNext के लिए बेकिंग में देखेंगे। –

+0

त्वरित अनुवर्ती के लिए धन्यवाद! – Jeff

0

मैं यहां पूरी तरह से आधार से बाहर हो सकता हूं, लेकिन क्या आप IncludeNonPublicTypes() की तलाश नहीं कर रहे हैं?

From the documentation:

पंजीयन गैर सरकारी प्रकार

डिफ़ॉल्ट केवल विधानसभा के बाहर से दिखाई प्रकार द्वारा पंजीकृत किया जाएगा। आप गैर सरकारी प्रकार में शामिल करना चाहते हैं, तो आपको पहले विधानसभा निर्दिष्ट करने के साथ शुरू करने के लिए, और फिर फोन IncludeNonPublicTypes है

container.Register(
    AllTypes.FromThisAssembly() 
     .IncludeNonPublicTypes() 
     .BasedOn<NonPublicComponent>() 
); 
+0

नहीं, मैं मैन्युअल रूप से अपना पंजीकरण कर रहा हूं। इस प्रकार का पंजीकरण ठीक हो रहा है, यह सिर्फ प्रॉक्सी पीढ़ी पर है जो इसे उड़ाता है (ऊपर उल्लिखित कोड के कारण)। – Jeff

+0

हम्मम्म। तब मुझे कोई जानकारी नहीं है। आप वास्तव में अपनी कक्षाएं सार्वजनिक नहीं कर सकते: पी। –

0

उस के लिए कारण यह है कि सिल्वरलाइट सुरक्षा मॉडल हमारे लिए एक प्रॉक्सी का निर्माण करने की अनुमति नहीं देता है एक आंतरिक प्रकार, यहां तक ​​कि InternalsVisibleTo के साथ भी।

+0

फिर आप डिज़ाइन दृष्टिकोण से इस पर पहुंचने का सुझाव कैसे देंगे? मैं वास्तव में नहीं चाहता कि मेरे कोड के सभी आंतरिक उपभोक्ता के सामने आ जाए ... केवल इंटरफेस ... धन्यवाद। – Jeff

+0

दिलचस्प साइड नोट ... मैंने अपने कोड में .NET 4.0 से DefaultProxyBuilder की प्रतिलिपि बनाई है, फिर मेरे विंडसर कंटेनर को एक डमी प्रॉक्सीफ़ैक्टरी के साथ बनाया है जो जेनरेटर फ़ील्ड को प्रॉक्सी जेनरेटर के साथ अपने नए DefaultProxyBuilder का जिक्र करता है ... और यह मेरे काम करता है इकाई परीक्षण! लेकिन मुझे लगता है कि जब मैं इसे एसएल रनटाइम के तहत वास्तव में चलाने की कोशिश करता हूं तो यह काम नहीं करेगा ... – Jeff

+0

हाँ, यह सिल्वरलाइट सुरक्षा सैंडबॉक्स में सिल्वरलाइट पर विफल रहता है, कम से कम यह तब हुआ जब मैंने परीक्षण चलाया। अगर आपको कोई समाधान मिल जाए तो इसे आज़माने के लिए स्वतंत्र महसूस करें, मुझे इसे सेंकने में खुशी है। –

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