| File: System\ComponentModel\Design\Serialization\ContainerCodeDomSerializer.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.CodeDom; namespace System.ComponentModel.Design.Serialization; /// <summary> /// This class is used to serialize things of type "IContainer". We route all containers /// to the designer host's container. /// </summary> internal class ContainerCodeDomSerializer : CodeDomSerializer { private const string ContainerName = "components"; private static ContainerCodeDomSerializer? s_defaultSerializer; /// <summary> /// Retrieves a default static instance of this serializer. /// </summary> internal static new ContainerCodeDomSerializer Default => s_defaultSerializer ??= new ContainerCodeDomSerializer(); /// <summary> /// We override this so we can always provide the correct container as a reference. /// </summary> protected override object DeserializeInstance(IDesignerSerializationManager manager, Type type, object?[]? parameters, string? name, bool addToContainer) { if (typeof(IContainer).IsAssignableFrom(type)) { object? obj = manager.GetService(typeof(IContainer)); if (obj is not null) { manager.SetName(obj, name!); return obj; } } return base.DeserializeInstance(manager, type, parameters, name, addToContainer); } /// <summary> /// Serializes the given object into a CodeDom object. We serialize an IContainer by /// declaring an IContainer member variable and then assigning a Container into it. /// </summary> public override object Serialize(IDesignerSerializationManager manager, object value) { CodeStatementCollection statements = []; CodeExpression lhs; if (manager.TryGetContext(out CodeTypeDeclaration? typeDecl) && manager.TryGetContext(out RootContext? rootCtx)) { CodeMemberField field = new(typeof(IContainer), ContainerName) { Attributes = MemberAttributes.Private }; typeDecl.Members.Add(field); lhs = new CodeFieldReferenceExpression(rootCtx.Expression, ContainerName); } else { CodeVariableDeclarationStatement var = new(typeof(IContainer), ContainerName); statements.Add(var); lhs = new CodeVariableReferenceExpression(ContainerName); } // Now create the container SetExpression(manager, value, lhs); CodeObjectCreateExpression objCreate = new(typeof(Container)); CodeAssignStatement assign = new(lhs, objCreate); assign.UserData[nameof(IContainer)] = nameof(IContainer); statements.Add(assign); return statements; } }