File: AuthoringOM\Serializer\SerializableTypeCodeDomSerializer.cs
Project: ndp\cdf\src\WF\Common\System.Workflow.ComponentModel.csproj (System.Workflow.ComponentModel)
namespace System.Workflow.ComponentModel.Serialization
{
    using System;
    using System.CodeDom;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.ComponentModel.Design.Serialization;
    using System.Collections;
    using System.Resources;
    using System.Workflow.ComponentModel.Design;
    using System.Collections.Generic;
    using Microsoft.CSharp;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Compiler;
    using System.CodeDom.Compiler;
    using System.IO;
    using System.Reflection;
    using System.Diagnostics;
 
    #region Class SerializableTypeCodeDomSerializer
    internal sealed class SerializableTypeCodeDomSerializer : CodeDomSerializer
    {
        private CodeDomSerializer originalSerializer;
 
        public SerializableTypeCodeDomSerializer(CodeDomSerializer originalSerializer)
        {
            if (originalSerializer == null)
                throw new ArgumentNullException("originalSerializer");
 
            this.originalSerializer = originalSerializer;
        }
 
        public override object Serialize(IDesignerSerializationManager manager, object value)
        {
            if (manager == null)
                throw new ArgumentNullException("manager");
 
            object result = null;
            if (value == null)
                return result;
 
            CodeStatementCollection statements = null;
            ExpressionContext cxt = manager.Context[typeof(ExpressionContext)] as ExpressionContext;
 
            if (value.GetType().GetConstructor(new Type[0]) != null)
            {
                if (value is ICollection)
                {
                    ExpressionContext varExct = null;
                    if (cxt != null)
                    {
                        if (cxt.PresetValue != value)
                        {
                            try
                            {
                                statements = new CodeStatementCollection();
                                CodeVariableReferenceExpression varExpression = AddVariableExpression(manager, statements, value);
                                varExct = new ExpressionContext(varExpression, value.GetType(), cxt.Owner, value);
                                manager.Context.Push(varExct);
                                result = this.originalSerializer.Serialize(manager, value);
                                if (result is CodeStatementCollection)
                                    statements.AddRange(result as CodeStatementCollection);
                                else if (result is CodeStatement)
                                    statements.Add(result as CodeStatement);
                                else if (result is CodeExpression)
                                    // If the returned result is an expression, it mostly likely means the collection
                                    // can not be serialized using statements, instead it has been serialized as resources.
                                    // In this case, we just over-write the variable init expression with the "GetObject"
                                    // expression for resource objects.
                                    statements.Add(new CodeAssignStatement(varExpression, result as CodeExpression));
 
                                result = statements;
                            }
                            finally
                            {
                                if (varExct != null)
                                    manager.Context.Pop();
                            }
                        }
                        else
                        {
                            result = this.originalSerializer.Serialize(manager, value);
                        }
                    }
                }
                else
                {
                    statements = new CodeStatementCollection();
                    CodeVariableReferenceExpression varExpression = AddVariableExpression(manager, statements, value);
                    SerializeProperties(manager, statements, value, new Attribute[] { DesignOnlyAttribute.No });
                    SerializeEvents(manager, statements, value, new Attribute[] { DesignOnlyAttribute.No });
                    result = statements;
                }
            }
            else if (cxt != null)
            {
                result = this.originalSerializer.Serialize(manager, value);
            }
 
            return result;
        }
 
        private CodeVariableReferenceExpression AddVariableExpression(IDesignerSerializationManager manager, CodeStatementCollection statements, object value)
        {
            string varName = GetUniqueName(manager, value).Replace('`', '_');
            CodeVariableDeclarationStatement varDecl = new CodeVariableDeclarationStatement(TypeDescriptor.GetClassName(value), varName);
            varDecl.InitExpression = new CodeObjectCreateExpression(TypeDescriptor.GetClassName(value), new CodeExpression[0]);
            statements.Add(varDecl);
            CodeVariableReferenceExpression varExpression = new CodeVariableReferenceExpression(varName);
            SetExpression(manager, value, varExpression);
 
            return varExpression;
        }
    }
    #endregion
}