Example #1
0
        private static void ExportCollection(ExportContext context, NameValueCollection collection, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(collection != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            for (int i = 0; i < collection.Count; i++)
            {
                writer.WriteMember(collection.GetKey(i));

                string[] values = collection.GetValues(i);

                if (values == null)
                {
                    writer.WriteNull();
                }
                else if (values.Length > 1)
                {
                    context.Export(values, writer);
                }
                else
                {
                    context.Export(values[0], writer);
                }
            }

            writer.WriteEndObject();
        }
Example #2
0
        internal static void ExportView(ExportContext context, DataView view, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(view != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            writer.WriteMember("columns");

            writer.WriteStartArray();
            foreach (DataColumn column in view.Table.Columns)
            {
                context.Export(column.ColumnName, writer);
            }
            writer.WriteEndArray();

            writer.WriteMember("rows");

            writer.WriteStartArray();
            foreach (DataRowView row in view)
            {
                context.Export(row.Row.ItemArray, writer);
            }
            writer.WriteEndArray();

            writer.WriteEndObject();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);
            
            if (_properties.Count == 0)
            {
                writer.WriteString(value.ToString());
            }
            else
            {
                writer.WriteStartObject();

                foreach (PropertyDescriptor property in _properties)
                {
                    object propertyValue = property.GetValue(value);
                
                    if (!JsonNull.LogicallyEquals(propertyValue))
                    {
                        writer.WriteMember(property.Name);
                        context.Export(propertyValue, writer);
                    }
                }

                writer.WriteEndObject();
            }
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);
            if (_properties.Count == 0)
            {
                writer.WriteString(value.ToString());
                return;
            }
            ObjectReferenceTracker objectReferenceTracker = null;

            try
            {
                writer.WriteStartObject();
                foreach (PropertyDescriptor property in _properties)
                {
                    object value2 = property.GetValue(value);
                    if (!JsonNull.LogicallyEquals(value2))
                    {
                        writer.WriteMember(property.Name);
                        if (objectReferenceTracker == null)
                        {
                            objectReferenceTracker = TrackObject(context, value);
                        }
                        context.Export(value2, writer);
                    }
                }
                writer.WriteEndObject();
            }
            finally
            {
                objectReferenceTracker?.Pop(value);
            }
        }
        protected virtual void Export(ExportContext context, JsonWriter writer)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            writer.WriteStartArray();
            IEnumerator enumerator = GetEnumerator();

            try
            {
                while (enumerator.MoveNext())
                {
                    object current = enumerator.Current;
                    context.Export(current, writer);
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
            writer.WriteEndArray();
        }
Example #6
0
        private void HandleExport(ScoreBook book, ExportContext context)
        {
            CommitChanges();
            string message;
            bool   hasError = true;

            try
            {
                context.Export(book);
                message  = ErrorStrings.ExportComplete;
                hasError = false;
                ExportManager.CommitExported(context);
            }
            catch (UserCancelledException)
            {
                // Do nothing
                return;
            }
            catch (InvalidTimeSignatureException ex)
            {
                int beatAt = ex.Tick / ScoreBook.Score.TicksPerBeat + 1;
                message = string.Format(ErrorStrings.InvalidTimeSignature, beatAt);
            }
            catch (Exception ex)
            {
                Program.DumpExceptionTo(ex, "export_exception.json");
                message = ErrorStrings.ExportFailed + Environment.NewLine + ex.Message;
            }

            ShowDiagnosticsResult(MainFormStrings.Export, message, hasError, context.Diagnostics);
        }
Example #7
0
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            context.Export(value, writer);
        }
Example #8
0
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            context.Export(value, writer);
        }
        public void TableExportedViaDataView()
        {
            DataTable table = new DataTable();

            ExportContext context = new ExportContext();
            TestDataViewExporter exporter = new TestDataViewExporter();
            context.Register(exporter);
            context.Export(table, new JsonRecorder());

            Assert.AreSame(table.DefaultView, exporter.LastExported);
        }
Example #10
0
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            if (_properties.Count == 0)
            {
                writer.WriteString(value.ToString());
            }
            else
            {
                ObjectReferenceTracker tracker = null;

                try
                {
                    writer.WriteStartObject();

                    foreach (PropertyDescriptor property in _properties)
                    {
                        object propertyValue = property.GetValue(value);

                        if (!JsonNull.LogicallyEquals(propertyValue))
                        {
                            writer.WriteMember(property.Name);

                            if (tracker == null)
                            {
                                //
                                // We are about to enter a deeper scope so
                                // start tracking the current object being
                                // exported. This will help to detect
                                // recursive references that may occur
                                // through this exporter deeper in the tree.
                                //

                                tracker = TrackObject(context, value);
                            }

                            context.Export(propertyValue, writer);
                        }
                    }

                    writer.WriteEndObject();
                }
                finally
                {
                    if (tracker != null)
                    {
                        tracker.Pop(value);
                    }
                }
            }
        }
Example #11
0
        private static void ExportMembers(ExportContext context, IEnumerable<KeyValuePair<string, object>> members, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(members != null);
            Debug.Assert(writer != null);

            foreach (var member in members)
            {
                writer.WriteMember(member.Key);
                context.Export(member.Value, writer);
            }
        }
        public void TableExportedViaDataView()
        {
            var table = new DataTable();

            var context  = new ExportContext();
            var exporter = new TestDataViewExporter();

            context.Register(exporter);
            context.Export(table, new JsonRecorder());

            Assert.AreSame(table.DefaultView, exporter.LastExported);
        }
Example #13
0
        private static void ExportMembers(ExportContext context, IEnumerable <KeyValuePair <string, object> > members, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(members != null);
            Debug.Assert(writer != null);

            foreach (var member in members)
            {
                writer.WriteMember(member.Key);
                context.Export(member.Value, writer);
            }
        }
        public void TableExportedViaItsExporter()
        {
            DataSet ds = new DataSet();
            ds.Tables.Add(new DataTable("Table1"));

            ExportContext context = new ExportContext();
            TestDataTableExporter exporter = new TestDataTableExporter();
            context.Register(exporter);
            context.Export(ds, new JsonRecorder());

            Assert.AreSame(ds.Tables[0], exporter.LastExported);
        }
Example #15
0
 private static void ExportRowView(ExportContext context, DataRowView rowView, JsonWriter writer)
 {
     Debug.Assert(context != null);
     Debug.Assert(rowView != null);
     Debug.Assert(writer != null);
     writer.WriteStartObject();
     foreach (DataColumn column in rowView.DataView.Table.Columns)
     {
         writer.WriteMember(column.ColumnName);
         context.Export(rowView[column.Ordinal], writer);
     }
     writer.WriteEndObject();
 }
        public void TableExportedViaItsExporter()
        {
            var ds = new DataSet();

            ds.Tables.Add(new DataTable("Table1"));

            var context  = new ExportContext();
            var exporter = new TestDataTableExporter();

            context.Register(exporter);
            context.Export(ds, new JsonRecorder());

            Assert.AreSame(ds.Tables[0], exporter.LastExported);
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);
            IEnumerable enumerable = (IEnumerable)value;

            writer.WriteStartArray();
            foreach (object item in enumerable)
            {
                context.Export(item, writer);
            }
            writer.WriteEndArray();
        }
        private static void ExportCollection(ExportContext context, NameValueCollection collection, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(collection != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            for (int i = 0; i < collection.Count; i++)
            {
                writer.WriteMember(collection.GetKey(i));

                string[] values = collection.GetValues(i);

                if (values == null)
                    writer.WriteNull();
                else if (values.Length > 1)
                    context.Export(values, writer);
                else
                    context.Export(values[0], writer);
            }

            writer.WriteEndObject();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);
            writer.WriteStartObject();
            IDictionary dictionary = (IDictionary)value;

            foreach (DictionaryEntry item in dictionary)
            {
                writer.WriteMember(item.Key.ToString());
                context.Export(item.Value, writer);
            }
            writer.WriteEndObject();
        }
        internal static void ExportView(ExportContext context, DataView view, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(view != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            writer.WriteMember("columns");

            writer.WriteStartArray();
            foreach (DataColumn column in view.Table.Columns)
                context.Export(column.ColumnName, writer);
            writer.WriteEndArray();

            writer.WriteMember("rows");

            writer.WriteStartArray();
            foreach (DataRowView row in view)
                context.Export(row.Row.ItemArray, writer);
            writer.WriteEndArray();

            writer.WriteEndObject();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            IEnumerable items = (IEnumerable) value;
            
            writer.WriteStartArray();

            foreach (object item in items)
                context.Export(item, writer);

            writer.WriteEndArray();
        }
        internal static void ExportRecord(ExportContext context, ICustomTypeDescriptor record, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(record != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            foreach (PropertyDescriptor property in record.GetProperties())
            {
                writer.WriteMember(property.Name);
                context.Export(property.GetValue(record), writer);
            }

            writer.WriteEndObject();
        }
Example #23
0
    public void Export(ExportContext context, object value, JsonWriter writer)
    {
        var properties = value.GetType().GetProperties();

        writer.WriteStartObject();
        foreach (var property in properties)
        {
            var propertyValue = property.GetValue(value, null);
            if (!JsonNull.LogicallyEquals(propertyValue))
            {
                writer.WriteMember(property.Name);
                context.Export(propertyValue, writer);
            }
        }
        writer.WriteEndObject();
    }
        internal static void ExportRow(ExportContext context, DataRow row, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(row != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();
    
            foreach (DataColumn column in row.Table.Columns)
            {
                writer.WriteMember(column.ColumnName);
                context.Export(row[column], writer);
            }
    
            writer.WriteEndObject();
        }
Example #25
0
        internal static void ExportRecord(ExportContext context, ICustomTypeDescriptor record, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(record != null);
            Debug.Assert(writer != null);
            
            writer.WriteStartObject();
                        
            foreach (PropertyDescriptor property in record.GetProperties())
            {
                writer.WriteMember(property.Name);
                context.Export(property.GetValue(record), writer);
            }

            writer.WriteEndObject();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            var dictionary = (IDictionary)value;

            foreach (var entry in DictionaryHelper.GetEntries(dictionary))
            {
                writer.WriteMember(entry.Key.ToString());
                context.Export(entry.Value, writer);
            }

            writer.WriteEndObject();
        }
Example #27
0
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();
            
            IDictionary dictionary = (IDictionary) value;
            
            foreach (DictionaryEntry entry in DictionaryHelper.GetEntries(dictionary))
            {
                writer.WriteMember(entry.Key.ToString());
                context.Export(entry.Value, writer);
            }

            writer.WriteEndObject();
        }
Example #28
0
 protected virtual void Export(ExportContext context, JsonWriter writer)
 {
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     if (writer == null)
     {
         throw new ArgumentNullException("writer");
     }
     writer.WriteStartObject();
     foreach (string nameIndex in NameIndexList)
     {
         writer.WriteMember(nameIndex);
         context.Export(base.InnerHashtable[nameIndex], writer);
     }
     writer.WriteEndObject();
 }
Example #29
0
        public void MemberExportCustomization()
        {
            var calls = new ArrayList();

            var logicalType = new TestTypeDescriptor();
            var properties  = logicalType.GetProperties();

            var memexp1  = new TestObjectMemberExporter(calls);
            var services = new Hashtable
            {
                [typeof(IObjectMemberExporter)] = memexp1
            };

            properties.Add(new TestPropertyDescriptor("prop1", services));

            var memexp2 = new TestObjectMemberExporter(calls);

            services = new Hashtable
            {
                [typeof(IObjectMemberExporter)] = memexp2
            };
            properties.Add(new TestPropertyDescriptor("prop2", services));

            var exporter = new ComponentExporter(typeof(Thing), logicalType);
            var context  = new ExportContext();

            context.Register(exporter);

            var writer = new JsonRecorder();
            var thing  = new Thing();

            context.Export(thing, writer);

            Assert.AreEqual(2, calls.Count);

            object[] args = { context, writer, thing };

            Assert.AreSame(memexp1, calls[0]);
            Assert.AreEqual(args, ((TestObjectMemberExporter)calls[0]).ExportArgs);

            Assert.AreSame(memexp2, calls[1]);
            Assert.AreEqual(args, ((TestObjectMemberExporter)calls[1]).ExportArgs);
        }
Example #30
0
        protected virtual void Export(ExportContext context, JsonWriter writer)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            writer.WriteStartArray();

            foreach (object value in this)
            {
                context.Export(value, writer);
            }

            writer.WriteEndArray();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();
            
            IDictionary dictionary = (IDictionary) value;
            
            foreach (DictionaryEntry entry in dictionary)
            {
                writer.WriteMember(entry.Key.ToString());
                context.Export(entry.Value, writer);
            }

            /*
             FIXME: Use IDictionaryEnumerator.Entry instead and enumerate manually (faster and more robust).
             It is faster because unboxing is avoided by going over
             IDictionaryEnumerator.Entry rather than 
             IDictionaryEnumerator.Current. It is more robust because many 
             people may get the implementation of IDictionary.GetEnumerator 
             wrong, especially if they are implementing IDictionary<K, V> in 
             2.0. If they simply return the enumerator from the wrapped
             dictionary then Current will return KeyValuePair<K, V> instead
             of DictionaryEntry and therefore cause a casting exception.
             
            using (IDictionaryEnumerator e = dictionary.GetEnumerator())
            {            
                while (e.MoveNext())
                {
                    writer.WriteMember(e.Entry.Key.ToString());
                    context.Export(e.Entry.Value, writer);
                }
            }
            */

            writer.WriteEndObject();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);

            writer.WriteStartObject();

            IDictionary dictionary = (IDictionary)value;

            foreach (DictionaryEntry entry in dictionary)
            {
                writer.WriteMember(entry.Key.ToString());
                context.Export(entry.Value, writer);
            }

            /*
             * FIXME: Use IDictionaryEnumerator.Entry instead and enumerate manually (faster and more robust).
             * It is faster because unboxing is avoided by going over
             * IDictionaryEnumerator.Entry rather than
             * IDictionaryEnumerator.Current. It is more robust because many
             * people may get the implementation of IDictionary.GetEnumerator
             * wrong, especially if they are implementing IDictionary<K, V> in
             * 2.0. If they simply return the enumerator from the wrapped
             * dictionary then Current will return KeyValuePair<K, V> instead
             * of DictionaryEntry and therefore cause a casting exception.
             *
             * using (IDictionaryEnumerator e = dictionary.GetEnumerator())
             * {
             *  while (e.MoveNext())
             *  {
             *      writer.WriteMember(e.Entry.Key.ToString());
             *      context.Export(e.Entry.Value, writer);
             *  }
             * }
             */

            writer.WriteEndObject();
        }
        protected override void ExportValue(ExportContext context, object value, JsonWriter writer)
        {
            Debug.Assert(context != null);
            Debug.Assert(value != null);
            Debug.Assert(writer != null);
            
            if (_properties.Count == 0)
            {
                writer.WriteString(value.ToString());
            }
            else
            {
                ObjectReferenceTracker tracker = null;
                
                try
                {
                    writer.WriteStartObject();
                    
                    int index = 0;

                    foreach (PropertyDescriptor property in _properties)
                    {
                        IObjectMemberExporter exporter = _exporters != null && index < _exporters.Length ? 
                            _exporters[index] : null;
                        
                        if (exporter != null)
                        {
                            exporter.Export(context, writer, value);
                        }
                        else
                        {
                            object propertyValue = property.GetValue(value);
                
                            if (!JsonNull.LogicallyEquals(propertyValue))
                            {
                                writer.WriteMember(property.Name);

                                if (tracker == null)
                                {
                                    //
                                    // We are about to enter a deeper scope so 
                                    // start tracking the current object being 
                                    // exported. This will help to detect 
                                    // recursive references that may occur 
                                    // through this exporter deeper in the tree.
                                    //
                                
                                    tracker = TrackObject(context, value);
                                }

                                context.Export(propertyValue, writer);
                            }
                        }
                    }

                    writer.WriteEndObject();
                }
                finally
                {
                    if (tracker != null)
                        tracker.Pop(value);
                }
            }
        }
        protected virtual void WriteResponse(object response, TextWriter output)
        {
            if (response == null)
                throw new ArgumentNullException("response");

            if (output == null)
                throw new ArgumentNullException("output");
            
            JsonWriter writer = (JsonWriter) _serviceProvider.GetService(typeof(JsonWriter));
            
            if (writer == null)
                writer = new JsonTextWriter(output);

            ExportContext exportContext = new ExportContext();
            exportContext.Export(response, writer);
        }
        public void MemberExportCustomization()
        {
            TestObjectMemberExporter memberExporter = new TestObjectMemberExporter();
            Hashtable services = new Hashtable();
            services.Add(typeof(IObjectMemberExporter), memberExporter);

            TestTypeDescriptor logicalType = new TestTypeDescriptor();
            PropertyDescriptorCollection properties = logicalType.GetProperties();
            properties.Add(new TestPropertyDescriptor("prop", services));
            
            ComponentExporter exporter = new ComponentExporter(typeof(Thing), logicalType);
            ExportContext context = new ExportContext();
            context.Register(exporter);
            
            JsonRecorder writer = new JsonRecorder();
            Thing thing = new Thing();
            context.Export(thing, writer);
            
            Assert.AreSame(context, memberExporter.ExportContext);
            Assert.AreSame(writer, memberExporter.ExportWriter);
            Assert.AreSame(thing, memberExporter.ExportSource);
        }
Example #36
0
        private static void Run()
        {
            ImportContext impctx = new ImportContext();

            //
            // Import a strongly-typed collection of integers...
            //

            impctx.Register(new ListImporter <int>());

            List <int> numbers = (List <int>)impctx.Import(typeof(List <int>),
                                                           JsonText.CreateReader("[ 1, 2, 3 ]"));

            numbers.ForEach(Console.WriteLine);
            Console.WriteLine();

            //
            // Import a Shape object containing a strongly-typed collection of
            // Point objects.
            //

            impctx.Register(new ListImporter <Point>());

            Shape shape = (Shape)impctx.Import(typeof(Shape), JsonText.CreateReader(@"{ 
                    name: 'square', 
                    points: [
                        { x: 10, y: 10 },
                        { x: 20, y: 10 }, 
                        { x: 20, y: 20 },
                        { x: 10, y: 20 }
                    ]
                }"));

            JsonConvert.Export(shape, CreatePrettyWriter(Console.Out));
            Console.WriteLine();

            //
            // Import CookieCollection using duck-typing. In other words,
            // as long as CookieCollection walks and quacks like a
            // collection of Cookie elements then it's good enough for
            // DuckCollectionImporter. DuckCollectionImporter can infer
            // that CookieCollection contains Cookie elements.
            //

            impctx.Register(new DuckCollectionImporter(typeof(CookieCollection)));

            const string cookiesText = @"[
                    { name: 'one',   value: 1, expires: '2099-01-02' },
                    { name: 'two',   value: 2, expires: '2088-03-04' },
                    { name: 'three', value: 3, expires: '2077-05-06' }
                ]";

            CookieCollection cookies = (CookieCollection)impctx.Import(typeof(CookieCollection), JsonText.CreateReader(cookiesText));

            JsonConvert.Export(cookies, CreatePrettyWriter(Console.Out));
            Console.WriteLine();

            //
            // Now repeat, but replace with a new CookieCollection importer
            // that is identical in behavior but based on generics. Here,
            // the difference is that DuckCollectionImporter<,> does not
            // have to guess the element type as it is provided as a type
            // argument.
            //

            impctx.Register(new DuckCollectionImporter <CookieCollection, Cookie>());
            cookies = (CookieCollection)impctx.Import(typeof(CookieCollection), JsonText.CreateReader(cookiesText));
            JsonConvert.Export(cookies, CreatePrettyWriter(Console.Out));
            Console.WriteLine();

            //
            // Those Cookie objects have a lot of properties. Say our JSON
            // text only needs a subset. Here, we register an exporter that
            // provides a custom view of the type. We only expose the name,
            // value and expiration time. What's more, we rename the
            // Expires property so that it appears as "expiration" in JSON.
            //

            ExportContext expctx = new ExportContext();

            JsonType.
            BuildFor(typeof(Cookie)).
            AddProperty("Name").
            AddProperty("Value").
            AddProperty("Expires").As("expiration").
            Register(expctx);

            expctx.Export(cookies, CreatePrettyWriter(Console.Out));
            Console.WriteLine();
        }
Example #37
0
        public void MemberExportCustomization()
        {
            ArrayList calls = new ArrayList();

            TestTypeDescriptor logicalType = new TestTypeDescriptor();
            PropertyDescriptorCollection properties = logicalType.GetProperties();

            Hashtable services;

            TestObjectMemberExporter memexp1 = new TestObjectMemberExporter(calls);
            services = new Hashtable();
            services.Add(typeof(IObjectMemberExporter), memexp1);
            properties.Add(new TestPropertyDescriptor("prop1", services));

            TestObjectMemberExporter memexp2 = new TestObjectMemberExporter(calls);
            services = new Hashtable();
            services.Add(typeof(IObjectMemberExporter), memexp2);
            properties.Add(new TestPropertyDescriptor("prop2", services));

            ComponentExporter exporter = new ComponentExporter(typeof(Thing), logicalType);
            ExportContext context = new ExportContext();
            context.Register(exporter);

            JsonRecorder writer = new JsonRecorder();
            Thing thing = new Thing();
            context.Export(thing, writer);

            Assert.AreEqual(2, calls.Count);

            object[] args = { context, writer, thing };

            Assert.AreSame(memexp1, calls[0]);
            Assert.AreEqual(args, ((TestObjectMemberExporter) calls[0]).ExportArgs);

            Assert.AreSame(memexp2, calls[1]);
            Assert.AreEqual(args, ((TestObjectMemberExporter) calls[1]).ExportArgs);
        }