2012-01-07 13 views
6

विभिन्न स्रोत यह मिश्रण समझाने किMarshalByRefObject और Serializable

एक वस्तु प्रपत्र MarshalByRefObject, एक वस्तु संदर्भ एक आवेदन डोमेन से दूसरे के बजाय वस्तु ही पारित हो जाएगा निकला है। जब किसी ऑब्जेक्ट को [सीरियलज़ेबल] के साथ चिह्नित किया जाता है, तो ऑब्जेक्ट स्वचालित रूप से क्रमबद्ध किया जाएगा, एक एप्लिकेशन डोमेन से दूसरे स्थान पर ले जाया जाएगा और फिर दूसरे एप्लिकेशन डोमेन में ऑब्जेक्ट की सटीक प्रतिलिपि बनाने के लिए deserialized किया जाएगा। नोट कि मार्शलबीरफॉब्जेक्ट एक संदर्भ पास करता है, [Serializable] ऑब्जेक्ट की प्रतिलिपि बनाने का कारण बनता है। [source]

मैं AppDomains का उपयोग करता है मेरा पहला एप्लिकेशन को डिजाइन कर रहा हूँ और मैं सोच रहा हूँ क्या होता है जब आप, MarshalByRefObjects serializable ऑब्जेक्ट MarshalByRefObject को लागू नहीं करते अंदर के लिए संदर्भ जगह क्योंकि अब तक मैं किसी भी प्रलेखन पर नहीं मिल सकता है विषय।

उदाहरण के लिए, यदि मैं List<MBR> वापस करने का प्रयास करता हूं तो MBR : MarshalByRefObject एक ऐपडोमेन सीमा में वापस करने का प्रयास करता है तो क्या होगा? क्या मुझे List<MBR> की एक प्रति प्राप्त होती है जहां प्रत्येक MBR मूल ऑब्जेक्ट पर TransparentProxy है? और क्या दो तंत्रों को मिलाकर तकनीकी विवरण के बारे में कोई दस्तावेज है?

उत्तर

7

मैं सिर्फ List<MBR> साथ एक त्वरित परीक्षण किया था और यह काम करने के लिए के रूप में मैं आशा व्यक्त की थी लगता है:

public class MBR : MarshalByRefObject 
{ 
    List<MBR> _list; 
    public MBR() { _list = new List<MBR> { this }; } 
    public IList<MBR> Test() { return _list; } 
    public int X { get; set; } 
} 

// Later... 
var mbr = AppDomainStarter.Start<MBR>(@"C:\Program Files", "test", null, true); 
var list = mbr.Test(); 
list[0].X = 42; 
list.Clear(); 
Debug.WriteLine(string.Format("X={0}, Count={1}", mbr.X, mbr.Test().Count)); 

उत्पादन X=42, Count=1 है, और डिबगर पता चलता है कि List<MBR> एक __TransparentProxy शामिल हैं। तो स्पष्ट रूप से, MarshalByRefObject को किसी अन्य ऑब्जेक्ट के अंदर संदर्भ द्वारा सफलतापूर्वक मार्शल किया गया है जिसे मूल्य द्वारा मार्शल किया गया था।

यदि कोई कुछ ढूंढ सकता है तो भी मैं दस्तावेज़ीकरण या तकनीकी विवरण देखना चाहता हूं।

जो कोई उत्सुक है के लिए, मैं इस आसान-dandy सैंडबॉक्स AppDomainStarter लिखा है:

/// <summary><see cref="AppDomainStarter.Start"/> starts an AppDomain.</summary> 
public static class AppDomainStarter 
{ 
    /// <summary>Creates a type in a new sandbox-friendly AppDomain.</summary> 
    /// <typeparam name="T">A trusted type derived MarshalByRefObject to create 
    /// in the new AppDomain. The constructor of this type must catch any 
    /// untrusted exceptions so that no untrusted exception can escape the new 
    /// AppDomain.</typeparam> 
    /// <param name="baseFolder">Value to use for AppDomainSetup.ApplicationBase. 
    /// The AppDomain will be able to use any assemblies in this folder.</param> 
    /// <param name="appDomainName">A friendly name for the AppDomain. MSDN 
    /// does not state whether or not the name must be unique.</param> 
    /// <param name="constructorArgs">Arguments to send to the constructor of T, 
    /// or null to call the default constructor. Do not send arguments of 
    /// untrusted types this way.</param> 
    /// <param name="partialTrust">Whether the new AppDomain should run in 
    /// partial-trust mode.</param> 
    /// <returns>A remote proxy to an instance of type T. You can call methods 
    /// of T and the calls will be marshalled across the AppDomain boundary.</returns> 
    public static T Start<T>(string baseFolder, string appDomainName, 
     object[] constructorArgs, bool partialTrust) 
     where T : MarshalByRefObject 
    { 
     // With help from http://msdn.microsoft.com/en-us/magazine/cc163701.aspx 
     AppDomainSetup setup = new AppDomainSetup(); 
     setup.ApplicationBase = baseFolder; 

     AppDomain newDomain; 
     if (partialTrust) { 
      var permSet = new PermissionSet(PermissionState.None); 
      permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 
      permSet.AddPermission(new UIPermission(PermissionState.Unrestricted)); 
      newDomain = AppDomain.CreateDomain(appDomainName, null, setup, permSet); 
     } else { 
      newDomain = AppDomain.CreateDomain(appDomainName, null, setup); 
     } 
     return (T)Activator.CreateInstanceFrom(newDomain, 
      typeof(T).Assembly.ManifestModule.FullyQualifiedName, 
      typeof(T).FullName, false, 
      0, null, constructorArgs, null, null).Unwrap(); 
    } 
} 
0

यह मेरी समझ है कि पारित होने वाली शीर्ष-स्तरीय वस्तु केवल एमबीआर हो सकती है। आपके परिदृश्य में, चूंकि सूची एमबीआर नहीं है, जब सीमा पार हो जाती है, तो आपको धारावाहिक प्रतियां प्राप्त होंगी।

MSDN documentation में यह खंड इस व्यवहार बताते हैं:

MarshalByRefObject वस्तुओं है कि एक प्रॉक्सी का उपयोग संदेशों का आदान द्वारा आवेदन डोमेन सीमाओं के पार संवाद के लिए आधार वर्ग है। ऑब्जेक्ट्स जो मार्शलबीरफॉबजेक्ट से प्राप्त नहीं होते हैं वे मूल्य से पूरी तरह से मार्शल हैं। जब एक रिमोट एप्लिकेशन मूल्य वस्तु द्वारा मार्शल का संदर्भ देता है, तो ऑब्जेक्ट की एक प्रति एप्लिकेशन डोमेन सीमाओं में पारित होती है।

इसलिए, चूंकि पारित वर्ग (सूची) एमबीआर नहीं है, इसलिए इसकी सामग्री के साथ इसे क्रमबद्ध किया जाएगा।

... वस्तु के सदस्यों आवेदन डोमेन जहां वे बनाए गए थे बाहर प्रयोग करने योग्य नहीं हैं:

इसके अलावा, जबकि सीधे सवाल पर लागू नहीं, निम्नलिखित व्यवहार नोट करने के लिए बहुत महत्वपूर्ण है।

+0

तो अगर एमबीआर Serializable नहीं है, वहाँ किसी तरह का एक अपवाद जब .नेट फ्रेमवर्क यह क्रमानुसार करने की कोशिश करता है हो जाएगा ? एमबीआर [] सरणी वापस करने के बारे में क्या? System.Array Serializable है, और मार्शल ByRefObject से व्युत्पन्न नहीं है। – Qwertie

+0

फिर serializable नहीं है: हाँ, रनटाइम पर एक अपवाद होगा। फिर एमबीआर सरणी: आपके पास सूची के समान समस्या है क्योंकि सरणी शीर्ष-स्तरीय कक्षा है। –

+2

प्रयोग से पता चलता है कि एक धारावाहिक कंटेनर के अंदर एक गैर-धारावाहिक एमबीआर अपवाद के बिना संदर्भ द्वारा पारित हो जाता है। –

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