Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -0,0 +1,124 @@
//------------------------------------------------------------------------------
// <copyright file="ComponentSerializationService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Security.Permissions;
/// <devdoc>
/// This class serializes a set of components or serializable objects into a
/// serialization store. The store can then be deserialized at a later
/// date. ComponentSerializationService differs from other serialization
/// schemes in that the serialization format is opaque, and it allows for
/// partial serialization of objects. For example, you can choose to
/// serialize only selected properties for an object.
///
/// This class is abstract. Typically a DesignerLoader will provide a
/// concrete implementation of this class and add it as a service to
/// its DesignSurface. This allows objects to be serialized in the
/// format best suited for them.
/// </devdoc>
[HostProtection(SharedState = true)]
public abstract class ComponentSerializationService
{
/// <devdoc>
/// This method creates a new SerializationStore. The serialization store can
/// be passed to any of the various Serialize methods to build up serialization
/// state for a group of objects.
/// </devdoc>
public abstract SerializationStore CreateStore();
/// <devdoc>
/// This method loads a SerializationStore and from the given
/// stream. This store can then be used to deserialize objects by passing it to
/// the various Deserialize methods.
/// </devdoc>
public abstract SerializationStore LoadStore(Stream stream);
/// <devdoc>
/// This method serializes the given object to the store. The store
/// can be used to serialize more than one object by calling this method
/// more than once.
/// </devdoc>
public abstract void Serialize(SerializationStore store, object value);
/// <devdoc>
/// Normal serialization only serializes values that differ from the component's default state.
/// This provides the most compact serialization mechanism but assumes that during deserilalization
/// a new, freshly created object will be used. If an existing object is used properties that
/// contained default values during serialization would not be reset back to their defaults.
/// The SerializeAbsolute method does not require this assumption on the deserializing end.
/// Instead, it saves data in the serialization store about default values as well so that
/// deserialization can reset non-default properties back to their default values. This is
/// especially true for collection objects, where the collections are either cleared and
/// items re-added, or individual items are removed and added.
/// </devdoc>
public abstract void SerializeAbsolute(SerializationStore store, object value);
/// <devdoc>
/// This method serializes the given member on the given object. This method
/// can be invoked multiple times for the same object to build up a list of
/// serialized members within the serialization store. The member generally
/// has to be a property or an event.
/// </devdoc>
public abstract void SerializeMember(SerializationStore store, object owningObject, MemberDescriptor member);
/// <devdoc>
/// This method serializes the given member on the given object,
/// but also serializes the member if it contains the default value.
/// Note that for some members, containing the default value and setting
/// the same value back to the member are different concepts. For example,
/// if a property inherits its value from a parent object if no local value
/// is set, setting the value back to the property can may not be what is desired.
/// SerializeMemberAbsolute takes this into account and would clear the state of
/// the property in this case.
/// </devdoc>
public abstract void SerializeMemberAbsolute(SerializationStore store, object owningObject, MemberDescriptor member);
/// <devdoc>
/// This method deserializes the given store to produce a collection of
/// objects contained within it. If a container is provided, objects
/// that are created that implement IComponent will be added to the container.
/// </devdoc>
public abstract ICollection Deserialize(SerializationStore store);
/// <devdoc>
/// This method deserializes the given store to produce a collection of
/// objects contained within it. If a container is provided, objects
/// that are created that implement IComponent will be added to the container.
/// </devdoc>
public abstract ICollection Deserialize(SerializationStore store, IContainer container);
/// <devdoc>
/// This method deserializes the given store, but rather than produce
/// new objects, the data in the store is applied to an existing
/// set of objects that are taken from the provided container. This
/// allows the caller to pre-create an object however it sees fit. If
/// an object has deserialization state and the object is not named in
/// the set of existing objects, a new object will be created. If that
/// object also implements IComponent, it will be added to the given
/// container. Objects in the container must have names that
/// match objects in the serialization store in order for an existing
/// object to be used. If validateRecycledTypes is true it is guaranteed
/// that the deserialization will only work if applied to an object of the
/// same type.
/// </devdoc>
public abstract void DeserializeTo(SerializationStore store, IContainer container, bool validateRecycledTypes, bool applyDefaults);
public void DeserializeTo(SerializationStore store, IContainer container) {
DeserializeTo(store, container, true, true);
}
public void DeserializeTo(SerializationStore store, IContainer container, bool validateRecycledTypes) {
DeserializeTo(store, container, validateRecycledTypes, true);
}
}
}

View File

@@ -0,0 +1,137 @@
//------------------------------------------------------------------------------
// <copyright file="ContextStack.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Collections;
using System.Security.Permissions;
/// <devdoc>
/// A context stack is an object that can be used by serializers
/// to push various context objects. Serialization is often
/// a deeply nested operation, involving many different
/// serialization classes. These classes often need additional
/// context information when performing serialization. As
/// an example, an object with a property named "Enabled" may have
/// a data type of System.Boolean. If a serializer is writing
/// this value to a data stream it may want to know what property
/// it is writing. It won't have this information, however, because
/// it is only instructed to write the boolean value. In this
/// case the parent serializer may push a PropertyDescriptor
/// pointing to the "Enabled" property on the context stack.
/// What objects get pushed on this stack are up to the
/// individual serializer objects.
/// </devdoc>
[HostProtection(SharedState = true)]
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
public sealed class ContextStack {
private ArrayList contextStack;
/// <devdoc>
/// Retrieves the current object on the stack, or null
/// if no objects have been pushed.
/// </devdoc>
public object Current {
get {
if (contextStack != null && contextStack.Count > 0) {
return contextStack[contextStack.Count - 1];
}
return null;
}
}
/// <devdoc>
/// Retrieves the object on the stack at the given
/// level, or null if no object exists at that level.
/// </devdoc>
public object this[int level] {
get {
if (level < 0) {
throw new ArgumentOutOfRangeException("level");
}
if (contextStack != null && level < contextStack.Count) {
return contextStack[contextStack.Count - 1 - level];
}
return null;
}
}
/// <devdoc>
/// Retrieves the first object on the stack that
/// inherits from or implements the given type, or
/// null if no object on the stack implements the type.
/// </devdoc>
public object this[Type type] {
get {
if (type == null) {
throw new ArgumentNullException("type");
}
if (contextStack != null) {
int level = contextStack.Count;
while(level > 0) {
object value = contextStack[--level];
if (type.IsInstanceOfType(value)) {
return value;
}
}
}
return null;
}
}
/// <devdoc>
/// Appends an object to the end of the stack, rather than pushing it
/// onto the top of the stack. This method allows a serializer to communicate
/// with other serializers by adding contextual data that does not have to
/// be popped in order. There is no way to remove an object that was
/// appended to the end of the stack without popping all other objects.
/// </devdoc>
public void Append(object context) {
if (context == null) {
throw new ArgumentNullException("context");
}
if (contextStack == null) {
contextStack = new ArrayList();
}
contextStack.Insert(0, context);
}
/// <devdoc>
/// Pops the current object off of the stack, returning
/// its value.
/// </devdoc>
public object Pop() {
object context = null;
if (contextStack != null && contextStack.Count > 0) {
int idx = contextStack.Count - 1;
context = contextStack[idx];
contextStack.RemoveAt(idx);
}
return context;
}
/// <devdoc>
/// Pushes the given object onto the stack.
/// </devdoc>
public void Push(object context) {
if (context == null) {
throw new ArgumentNullException("context");
}
if (contextStack == null) {
contextStack = new ArrayList();
}
contextStack.Add(context);
}
}
}

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
// <copyright file="DefaultSerializationProviderAttribute.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Security.Permissions;
/// <devdoc>
/// The default serialization provider attribute is placed on a serializer
/// to indicate the class to use as a default provider of that type of
/// serializer. To be a default serialization provider, a class must
/// implement IDesignerSerilaizationProvider and have an empty
/// constructor. The class itself can be internal to the assembly.
/// </devdoc>
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public sealed class DefaultSerializationProviderAttribute : Attribute {
private string _providerTypeName;
/// <devdoc>
/// Creates a new DefaultSerializationProviderAttribute
/// </devdoc>
public DefaultSerializationProviderAttribute(Type providerType) {
if (providerType == null) {
throw new ArgumentNullException("providerType");
}
_providerTypeName = providerType.AssemblyQualifiedName;
}
/// <devdoc>
/// Creates a new DefaultSerializationProviderAttribute
/// </devdoc>
public DefaultSerializationProviderAttribute(string providerTypeName) {
if (providerTypeName == null) {
throw new ArgumentNullException("providerTypeName");
}
_providerTypeName = providerTypeName;
}
/// <devdoc>
/// Returns the type name for the default serialization provider.
/// </devdoc>
public string ProviderTypeName {
get {
return _providerTypeName;
}
}
}
}

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <copyright file="DesignerLoader.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Reflection;
using System.Security.Permissions;
/// <devdoc>
/// DesignerLoader. This class is responsible for loading a designer document.
/// Where and how this load occurs is a private matter for the designer loader.
/// The designer loader will be handed to an IDesignerHost instance. This instance,
/// when it is ready to load the document, will call BeginLoad, passing an instance
/// of IDesignerLoaderHost. The designer loader will load up the design surface
/// using the host interface, and call EndLoad on the interface when it is done.
/// The error collection passed into EndLoad should be empty or null to indicate a
/// successful load, or it should contain a collection of exceptions that
/// describe the error.
///
/// Once a document is loaded, the designer loader is also responsible for
/// writing any changes made to the document back whatever storage the
/// loader used when loading the document.
/// </devdoc>
[HostProtection(SharedState = true)]
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class DesignerLoader {
/// <devdoc>
/// Returns true when the designer is in the process of loading. Clients that are
/// sinking notifications from the designer often want to ignore them while the desingner is loading
/// and only respond to them if they result from user interatcions.
/// </devdoc>
public virtual bool Loading {
get {
return false;
}
}
/// <devdoc>
/// Called by the designer host to begin the loading process. The designer
/// host passes in an instance of a designer loader host (which is typically
/// the same object as the designer host. This loader host allows
/// the designer loader to reload the design document and also allows
/// the designer loader to indicate that it has finished loading the
/// design document.
/// </devdoc>
public abstract void BeginLoad(IDesignerLoaderHost host);
/// <devdoc>
/// Disposes this designer loader. The designer host will call this method
/// when the design document itself is being destroyed. Once called, the
/// designer loader will never be called again.
/// </devdoc>
public abstract void Dispose();
/// <devdoc>
/// The designer host will call this periodically when it wants to
/// ensure that any changes that have been made to the document
/// have been saved by the designer loader. This method allows
/// designer loaders to implement a lazy-write scheme to improve
/// performance. The default implementation does nothing.
/// </devdoc>
public virtual void Flush() {}
}
}

View File

@@ -0,0 +1,87 @@
//------------------------------------------------------------------------------
// <copyright file="DesignerSerializerAttribute.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Security.Permissions;
/// <devdoc>
/// This attribute can be placed on a class to indicate what serialization
/// object should be used to serialize the class at design time.
/// </devdoc>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
public sealed class DesignerSerializerAttribute : Attribute {
private string serializerTypeName;
private string serializerBaseTypeName;
private string typeId;
/// <devdoc>
/// Creates a new designer serialization attribute.
/// </devdoc>
public DesignerSerializerAttribute(Type serializerType, Type baseSerializerType) {
this.serializerTypeName = serializerType.AssemblyQualifiedName;
this.serializerBaseTypeName = baseSerializerType.AssemblyQualifiedName;
}
/// <devdoc>
/// Creates a new designer serialization attribute.
/// </devdoc>
public DesignerSerializerAttribute(string serializerTypeName, Type baseSerializerType) {
this.serializerTypeName = serializerTypeName;
this.serializerBaseTypeName = baseSerializerType.AssemblyQualifiedName;
}
/// <devdoc>
/// Creates a new designer serialization attribute.
/// </devdoc>
public DesignerSerializerAttribute(string serializerTypeName, string baseSerializerTypeName) {
this.serializerTypeName = serializerTypeName;
this.serializerBaseTypeName = baseSerializerTypeName;
}
/// <devdoc>
/// Retrieves the fully qualified type name of the serializer.
/// </devdoc>
public string SerializerTypeName {
get {
return serializerTypeName;
}
}
/// <devdoc>
/// Retrieves the fully qualified type name of the serializer base type.
/// </devdoc>
public string SerializerBaseTypeName {
get {
return serializerBaseTypeName;
}
}
/// <internalonly/>
/// <devdoc>
/// <para>
/// This defines a unique ID for this attribute type. It is used
/// by filtering algorithms to identify two attributes that are
/// the same type. For most attributes, this just returns the
/// Type instance for the attribute. EditorAttribute overrides
/// this to include the type of the editor base type.
/// </para>
/// </devdoc>
public override object TypeId {
get {
if (typeId == null) {
string baseType = serializerBaseTypeName;
int comma = baseType.IndexOf(',');
if (comma != -1) {
baseType = baseType.Substring(0, comma);
}
typeId = GetType().FullName + baseType;
}
return typeId;
}
}
}
}

View File

@@ -0,0 +1,54 @@
//------------------------------------------------------------------------------
// <copyright file="IDesignerLoaderHost.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Collections;
using System.ComponentModel.Design;
/// <devdoc>
/// IDesignerLoaderHost. This is an extension of IDesignerHost that is passed
/// to the designer loader in the BeginLoad method. It is isolated from
/// IDesignerHost to emphasize that all loading and reloading of the design
/// document actually should be initiated by the designer loader, and not by
/// the designer host. However, the loader must inform the designer host that
/// it wishes to invoke a load or reload.
/// </devdoc>
public interface IDesignerLoaderHost : IDesignerHost {
/// <devdoc>
/// This is called by the designer loader to indicate that the load has
/// terminated. If there were errors, they should be passed in the errorCollection
/// as a collection of exceptions (if they are not exceptions the designer
/// loader host may just call ToString on them). If the load was successful then
/// errorCollection should either be null or contain an empty collection.
/// </devdoc>
void EndLoad(string baseClassName, bool successful, ICollection errorCollection);
/// <devdoc>
/// This is called by the designer loader when it wishes to reload the
/// design document. The reload will happen immediately so the caller
/// should ensure that it is in a state where BeginLoad may be called again.
/// </devdoc>
void Reload();
}
/// <devdoc>
/// IgnoreErrorsDuringReload - specifies whether errors should be ignored when Reload() is called.
/// We only allow to set to true if we CanReloadWithErrors. If we cannot
/// we simply ignore rather than throwing an exception. We probably should,
/// but we are avoiding localization.
/// CanReloadWithErrors - specifies whether it is possible to reload with errors. There are certain
/// scenarios where errors cannot be ignored.
/// </devdoc>
public interface IDesignerLoaderHost2 : IDesignerLoaderHost {
bool IgnoreErrorsDuringReload{ get; set;}
bool CanReloadWithErrors{ get; set;}
}
}

View File

@@ -0,0 +1,51 @@
//------------------------------------------------------------------------------
// <copyright file="IDesignerLoaderService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Collections;
/// <devdoc>
/// This interface may be optionally implemented by the designer loader to provide
/// load services to outside components. It provides support for asynchronous loading
/// of the designer and allows other objects to initiate a reload of othe
/// design surface. Designer loaders do not need to implement this but it is
/// recommended. We do not directly put this on DesignerLoader so we can prevent
/// outside objects from interacting with the main methods of a designer loader.
/// These should only be called by the designer host.
/// </devdoc>
public interface IDesignerLoaderService {
/// <devdoc>
/// Adds a load dependency to this loader. This indicates that some other
/// object is also participating in the load, and that the designer loader
/// should not call EndLoad on the loader host until all load dependencies
/// have called DependentLoadComplete on the designer loader.
/// </devdoc>
void AddLoadDependency();
/// <devdoc>
/// This is called by any object that has previously called
/// AddLoadDependency to signal that the dependent load has completed.
/// The caller should pass either an empty collection or null to indicate
/// a successful load, or a collection of exceptions that indicate the
/// reason(s) for failure.
/// </devdoc>
void DependentLoadComplete(bool successful, ICollection errorCollection);
/// <devdoc>
/// This can be called by an outside object to request that the loader
/// reload the design document. If it supports reloading and wants to
/// comply with the reload, the designer loader should return true. Otherwise
/// it should return false, indicating that the reload will not occur.
/// Callers should not rely on the reload happening immediately; the
/// designer loader may schedule this for some other time, or it may
/// try to reload at once.
/// </devdoc>
bool Reload();
}
}

View File

@@ -0,0 +1,130 @@
//------------------------------------------------------------------------------
// <copyright file="IDesignerSerializationManager.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Collections;
using System.ComponentModel;
/// <devdoc>
/// This interface is passed to a designer serializer to provide
/// assistance in the serialization process.
/// </devdoc>
public interface IDesignerSerializationManager : IServiceProvider {
/// <devdoc>
/// The Context property provides a user-defined storage area
/// implemented as a stack. This storage area is a useful way
/// to provide communication across serializers, as serialization
/// is a generally hierarchial process.
/// </devdoc>
ContextStack Context {get;}
/// <devdoc>
/// The Properties property provides a set of custom properties
/// the serialization manager may surface. The set of properties
/// exposed here is defined by the implementor of
/// IDesignerSerializationManager.
/// </devdoc>
PropertyDescriptorCollection Properties {get;}
/// <devdoc>
/// ResolveName event. This event
/// is raised when GetName is called, but the name is not found
/// in the serialization manager's name table. It provides a
/// way for a serializer to demand-create an object so the serializer
/// does not have to order object creation by dependency. This
/// delegate is cleared immediately after serialization or deserialization
/// is complete.
/// </devdoc>
event ResolveNameEventHandler ResolveName;
/// <devdoc>
/// This event is raised when serialization or deserialization
/// has been completed. Generally, serialization code should
/// be written to be stateless. Should some sort of state
/// be necessary to maintain, a serializer can listen to
/// this event to know when that state should be cleared.
/// An example of this is if a serializer needs to write
/// to another file, such as a resource file. In this case
/// it would be inefficient to design the serializer
/// to close the file when finished because serialization of
/// an object graph generally requires several serializers.
/// The resource file would be opened and closed many times.
/// Instead, the resource file could be accessed through
/// an object that listened to the SerializationComplete
/// event, and that object could close the resource file
/// at the end of serialization.
/// </devdoc>
event EventHandler SerializationComplete;
/// <devdoc>
/// This method adds a custom serialization provider to the
/// serialization manager. A custom serialization provider will
/// get the opportunity to return a serializer for a data type
/// before the serialization manager looks in the type's
/// metadata.
/// </devdoc>
void AddSerializationProvider(IDesignerSerializationProvider provider);
/// <devdoc>
/// Creates an instance of the given type and adds it to a collection
/// of named instances. Objects that implement IComponent will be
/// added to the design time container if addToContainer is true.
/// </devdoc>
object CreateInstance(Type type, ICollection arguments, string name, bool addToContainer);
/// <devdoc>
/// Retrieves an instance of a created object of the given name, or
/// null if that object does not exist.
/// </devdoc>
object GetInstance(string name);
/// <devdoc>
/// Retrieves a name for the specified object, or null if the object
/// has no name.
/// </devdoc>
string GetName(object value);
/// <devdoc>
/// Retrieves a serializer of the requested type for the given
/// object type.
/// </devdoc>
object GetSerializer(Type objectType, Type serializerType);
/// <devdoc>
/// Retrieves a type of the given name.
/// </devdoc>
Type GetType(string typeName);
/// <devdoc>
/// Removes a previously added serialization provider.
/// </devdoc>
void RemoveSerializationProvider(IDesignerSerializationProvider provider);
/// <devdoc>
/// Reports a non-fatal error in serialization. The serialization
/// manager may implement a logging scheme to alert the caller
/// to all non-fatal errors at once. If it doesn't, it should
/// immediately throw in this method, which should abort
/// serialization.
/// Serialization may continue after calling this function.
/// </devdoc>
void ReportError(object errorInformation);
/// <devdoc>
/// Provides a way to set the name of an existing object.
/// This is useful when it is necessary to create an
/// instance of an object without going through CreateInstance.
/// An exception will be thrown if you try to rename an existing
/// object or if you try to give a new object a name that
/// is already taken.
/// </devdoc>
void SetName(object instance, string name);
}
}

View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
// <copyright file="IDesignerSerializationProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
/// <devdoc>
/// This interface defines a custom serialization provider. This
/// allows outside objects to control serialization by providing
/// their own serializer objects.
/// </devdoc>
public interface IDesignerSerializationProvider {
/// <devdoc>
/// This will be called by the serialization manager when it
/// is trying to locate a serialzer for an object type.
/// If this serialization provider can provide a serializer
/// that is of the correct type, it should return it.
/// Otherwise, it should return null.
///
/// In order to break order dependencies between multiple
/// serialization providers the serialization manager will
/// loop through all serilaization provideres until the
/// serilaizer returned reaches steady state. Because
/// of this you should always check currentSerializer
/// before returning a new serializer. If currentSerializer
/// is an instance of your serializer, then you should
/// either return it or return null to prevent an infinite
/// loop.
/// </devdoc>
object GetSerializer(IDesignerSerializationManager manager, object currentSerializer, Type objectType, Type serializerType);
}
}

View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------------------------
// <copyright file="IDesignerSerializationService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Collections;
using System.ComponentModel;
/// <devdoc>
/// This service provides a way to exchange a collection of objects
/// for a serializable object that represents them. The returned
/// object contains live references to objects in the collection.
/// This returned object can then be passed to any runtime
/// serialization mechanism. The object itself serializes
/// components the same way designers write source for them; by picking
/// them apart property by property. Many objects do not support
/// runtime serialization because their internal state cannot be
/// adequately duplicated. All components that support a designer,
/// however, must support serialization by walking their public
/// properties, methods and events. This interface uses this
/// technique to convert a collection of components into a single
/// opaque object that does support runtime serialization.
/// </devdoc>
public interface IDesignerSerializationService {
/// <devdoc>
/// <para>
/// Deserializes the provided serialization data object and
/// returns a collection of objects contained within that
/// data.
/// </para>
/// </devdoc>
ICollection Deserialize(object serializationData);
/// <devdoc>
/// <para>
/// Serializes the given collection of objects and
/// stores them in an opaque serialization data object.
/// The returning object fully supports runtime serialization.
/// </para>
/// </devdoc>
object Serialize(ICollection objects);
}
}

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
// <copyright file="INameCreationService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Collections;
using System.ComponentModel.Design;
/// <devdoc>
/// This service may be provided by a designer loader to provide
/// a way for the designer to fabricate new names for objects.
/// If this service isn't available the designer will choose a
/// default implementation.
/// </devdoc>
public interface INameCreationService {
/// <devdoc>
/// Creates a new name that is unique to all the components
/// in the given container. The name will be used to create
/// an object of the given data type, so the service may
/// derive a name from the data type's name. The container
/// parameter can be null if no container search is needed.
/// </devdoc>
string CreateName(IContainer container, Type dataType);
/// <devdoc>
/// Determines if the given name is valid. A name
/// creation service may have rules defining a valid
/// name, and this method allows the sevice to enforce
/// those rules.
/// </devdoc>
bool IsValidName(string name);
/// <devdoc>
/// Determines if the given name is valid. A name
/// creation service may have rules defining a valid
/// name, and this method allows the sevice to enforce
/// those rules. It is similar to IsValidName, except
/// that this method will throw an exception if the
/// name is invalid. This allows implementors to provide
/// rich information in the exception message.
/// </devdoc>
void ValidateName(string name);
}
}

View File

@@ -0,0 +1,157 @@
//------------------------------------------------------------------------------
// <copyright file="InstanceDescriptor.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Security.Permissions;
/// <devdoc>
/// EventArgs for the ResolveNameEventHandler. This event is used
/// by the serialization process to match a name to an object
/// instance.
/// </devdoc>
[HostProtection(SharedState = true)]
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
public sealed class InstanceDescriptor {
private MemberInfo member;
private ICollection arguments;
private bool isComplete;
/// <devdoc>
/// Creates a new InstanceDescriptor.
/// </devdoc>
public InstanceDescriptor(MemberInfo member, ICollection arguments) : this(member, arguments, true) {
}
/// <devdoc>
/// Creates a new InstanceDescriptor.
/// </devdoc>
public InstanceDescriptor(MemberInfo member, ICollection arguments, bool isComplete) {
this.member = member;
this.isComplete = isComplete;
if (arguments == null) {
this.arguments = new object[0];
}
else {
object[] args = new object[arguments.Count];
arguments.CopyTo(args, 0);
this.arguments = args;
}
if (member is FieldInfo) {
FieldInfo fi = (FieldInfo)member;
if (!fi.IsStatic) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorMustBeStatic));
}
if (this.arguments.Count != 0) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorLengthMismatch));
}
}
else if (member is ConstructorInfo) {
ConstructorInfo ci = (ConstructorInfo)member;
if (ci.IsStatic) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorCannotBeStatic));
}
if (this.arguments.Count != ci.GetParameters().Length) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorLengthMismatch));
}
}
else if (member is MethodInfo) {
MethodInfo mi = (MethodInfo)member;
if (!mi.IsStatic) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorMustBeStatic));
}
if (this.arguments.Count != mi.GetParameters().Length) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorLengthMismatch));
}
}
else if (member is PropertyInfo) {
PropertyInfo pi = (PropertyInfo)member;
if (!pi.CanRead) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorMustBeReadable));
}
MethodInfo mi = pi.GetGetMethod();
if (mi != null && !mi.IsStatic) {
throw new ArgumentException(SR.GetString(SR.InstanceDescriptorMustBeStatic));
}
}
}
/// <devdoc>
/// The collection of arguments that should be passed to
/// MemberInfo in order to create an instance.
/// </devdoc>
public ICollection Arguments {
get {
return arguments;
}
}
/// <devdoc>
/// Determines if the contents of this instance descriptor completely identify the instance.
/// This will normally be the case, but some objects may be too complex for a single method
/// or constructor to represent. IsComplete can be used to identify these objects and take
/// additional steps to further describe their state.
/// </devdoc>
public bool IsComplete {
get {
return isComplete;
}
}
/// <devdoc>
/// The MemberInfo object that was passed into the constructor
/// of this InstanceDescriptor.
/// </devdoc>
public MemberInfo MemberInfo {
get {
return member;
}
}
/// <devdoc>
/// Invokes this instance descriptor, returning the object
/// the descriptor describes.
/// </devdoc>
public object Invoke() {
object[] translatedArguments = new object[arguments.Count];
arguments.CopyTo(translatedArguments, 0);
// Instance descriptors can contain other instance
// descriptors. Translate them if necessary.
//
for(int i = 0; i < translatedArguments.Length; i++) {
if (translatedArguments[i] is InstanceDescriptor) {
translatedArguments[i] = ((InstanceDescriptor)translatedArguments[i]).Invoke();
}
}
if (member is ConstructorInfo) {
return ((ConstructorInfo)member).Invoke(translatedArguments);
}
else if (member is MethodInfo) {
return ((MethodInfo)member).Invoke(null, translatedArguments);
}
else if (member is PropertyInfo) {
return ((PropertyInfo)member).GetValue(null, translatedArguments);
}
else if (member is FieldInfo) {
return ((FieldInfo)member).GetValue(null);
}
else {
Debug.Fail("Unrecognized reflection type in instance descriptor: " + member.GetType().Name);
}
return null;
}
}
}

View File

@@ -0,0 +1,241 @@
//------------------------------------------------------------------------------
// <copyright file="MemberRelationshipService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Security.Permissions;
/// <devdoc>
/// A member relationship service is used by a serializer to announce that one
/// property is related to a property on another object. Consider a code
/// based serialization scheme where code is of the following form:
///
/// object1.Property1 = object2.Property2
///
/// Upon interpretation of this code, Property1 on object1 will be
/// set to the return value of object2.Property2. But the relationship
/// between these two objects is lost. Serialization schemes that
/// wish to maintain this relationship may install a MemberRelationshipService
/// into the serialization manager. When an object is deserialized
/// this serivce will be notified of these relationships. It is up to the service
/// to act on these notifications if it wishes. During serialization, the
/// service is also consulted. If a relationship exists the same
/// relationship is maintained by the serializer.
/// </devdoc>
[HostProtection(SharedState = true)]
public abstract class MemberRelationshipService
{
private Dictionary<RelationshipEntry,RelationshipEntry> _relationships = new Dictionary<RelationshipEntry,RelationshipEntry>();
/// <devdoc>
/// Returns the the current relationship associated with the source, or MemberRelationship.Empty if
/// there is no relationship. Also sets a relationship between two objects. Empty
/// can also be passed as the property value, in which case the relationship will
/// be cleared.
/// </devdoc>
[SuppressMessage("Microsoft.Design", "CA1043:UseIntegralOrStringArgumentForIndexers")]
public MemberRelationship this[MemberRelationship source] {
get {
if (source.Owner == null) throw new ArgumentNullException("Owner");
if (source.Member== null) throw new ArgumentNullException("Member");
return GetRelationship(source);
}
set {
if (source.Owner == null) throw new ArgumentNullException("Owner");
if (source.Member == null) throw new ArgumentNullException("Member");
SetRelationship(source, value);
}
}
/// <devdoc>
/// Returns the the current relationship associated with the source, or null if
/// there is no relationship. Also sets a relationship between two objects. Null
/// can be passed as the property value, in which case the relationship will
/// be cleared.
/// </devdoc>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1023:IndexersShouldNotBeMultidimensional")]
public MemberRelationship this[object sourceOwner, MemberDescriptor sourceMember] {
get {
if (sourceOwner == null) throw new ArgumentNullException("sourceOwner");
if (sourceMember == null) throw new ArgumentNullException("sourceMember");
return GetRelationship(new MemberRelationship(sourceOwner, sourceMember));
}
set {
if (sourceOwner == null) throw new ArgumentNullException("sourceOwner");
if (sourceMember == null) throw new ArgumentNullException("sourceMember");
SetRelationship(new MemberRelationship(sourceOwner, sourceMember), value);
}
}
/// <devdoc>
/// This is the implementation API for returning relationships. The default implementation stores the
/// relationship in a table. Relationships are stored weakly, so they do not keep an object alive.
/// </devdoc>
protected virtual MemberRelationship GetRelationship(MemberRelationship source) {
RelationshipEntry retVal;
if (_relationships != null && _relationships.TryGetValue(new RelationshipEntry(source), out retVal) && retVal.Owner.IsAlive) {
return new MemberRelationship(retVal.Owner.Target, retVal.Member);
}
return MemberRelationship.Empty;
}
/// <devdoc>
/// This is the implementation API for returning relationships. The default implementation stores the
/// relationship in a table. Relationships are stored weakly, so they do not keep an object alive. Empty can be
/// passed in for relationship to remove the relationship.
/// </devdoc>
protected virtual void SetRelationship(MemberRelationship source, MemberRelationship relationship) {
if (!relationship.IsEmpty && !SupportsRelationship(source, relationship)) {
string sourceName = TypeDescriptor.GetComponentName(source.Owner);
string relName = TypeDescriptor.GetComponentName(relationship.Owner);
if (sourceName == null) {
sourceName = source.Owner.ToString();
}
if (relName == null) {
relName = relationship.Owner.ToString();
}
throw new ArgumentException(SR.GetString(SR.MemberRelationshipService_RelationshipNotSupported, sourceName, source.Member.Name, relName, relationship.Member.Name));
}
if (_relationships == null) {
_relationships = new Dictionary<RelationshipEntry,RelationshipEntry>();
}
_relationships[new RelationshipEntry(source)] = new RelationshipEntry(relationship);
}
/// <devdoc>
/// Returns true if the provided relatinoship is supported.
/// </devdoc>
public abstract bool SupportsRelationship(MemberRelationship source, MemberRelationship relationship);
/// <devdoc>
/// Used as storage in our relationship table
/// </devdoc>
private struct RelationshipEntry {
internal WeakReference Owner;
internal MemberDescriptor Member;
private int hashCode;
internal RelationshipEntry(MemberRelationship rel) {
Owner = new WeakReference(rel.Owner);
Member = rel.Member;
hashCode = rel.Owner == null ? 0 : rel.Owner.GetHashCode();
}
public override bool Equals(object o) {
if (o is RelationshipEntry) {
RelationshipEntry e = (RelationshipEntry)o;
return this == e;
}
return false;
}
public static bool operator==(RelationshipEntry re1, RelationshipEntry re2){
object owner1 = (re1.Owner.IsAlive ? re1.Owner.Target : null);
object owner2 = (re2.Owner.IsAlive ? re2.Owner.Target : null);
return owner1 == owner2 && re1.Member.Equals(re2.Member);
}
public static bool operator!=(RelationshipEntry re1, RelationshipEntry re2){
return !(re1 == re2);
}
public override int GetHashCode() {
return hashCode;
}
}
}
/// <devdoc>
/// This class represents a single relationship between an object and a member.
/// </devdoc>
public struct MemberRelationship {
private object _owner;
private MemberDescriptor _member;
public static readonly MemberRelationship Empty = new MemberRelationship();
/// <devdoc>
/// Creates a new member relationship.
/// </devdoc>
public MemberRelationship(object owner, MemberDescriptor member) {
if (owner == null) throw new ArgumentNullException("owner");
if (member == null) throw new ArgumentNullException("member");
_owner = owner;
_member = member;
}
/// <devdoc>
/// Returns true if this relationship is empty.
/// </devdoc>
public bool IsEmpty {
get {
return _owner == null;
}
}
/// <devdoc>
/// The member in this relationship.
/// </devdoc>
public MemberDescriptor Member {
get {
return _member;
}
}
/// <devdoc>
/// The object owning the member.
/// </devdoc>
public object Owner {
get {
return _owner;
}
}
/// <devdoc>
/// Infrastructure support to make this a first class struct
/// </devdoc>
public override bool Equals(object obj) {
if (!(obj is MemberRelationship))
return false;
MemberRelationship rel = (MemberRelationship)obj;
return rel.Owner == Owner && rel.Member == Member;
}
/// <devdoc>
/// Infrastructure support to make this a first class struct
/// </devdoc>
public override int GetHashCode() {
if (_owner == null) return base.GetHashCode();
return _owner.GetHashCode() ^ _member.GetHashCode();
}
/// <devdoc>
/// Infrastructure support to make this a first class struct
/// </devdoc>
public static bool operator ==(MemberRelationship left, MemberRelationship right) {
return left.Owner == right.Owner && left.Member == right.Member;
}
/// <devdoc>
/// Infrastructure support to make this a first class struct
/// </devdoc>
public static bool operator !=(MemberRelationship left, MemberRelationship right) {
return !(left == right);
}
}
}

View File

@@ -0,0 +1,54 @@
//------------------------------------------------------------------------------
// <copyright file="ResolveNameEventArgs.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System;
using System.Security.Permissions;
/// <devdoc>
/// EventArgs for the ResolveNameEventHandler. This event is used
/// by the serialization process to match a name to an object
/// instance.
/// </devdoc>
[HostProtection(SharedState = true)]
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name = "FullTrust")]
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")]
public class ResolveNameEventArgs : EventArgs {
private string name;
private object value;
/// <devdoc>
/// Creates a new resolve name event args object.
/// </devdoc>
public ResolveNameEventArgs(string name) {
this.name = name;
this.value = null;
}
/// <devdoc>
/// The name of the object that needs to be resolved.
/// </devdoc>
public string Name {
get {
return name;
}
}
/// <devdoc>
/// The object that matches the name.
/// </devdoc>
public object Value {
get {
return value;
}
set {
this.value = value;
}
}
}
}

View File

@@ -0,0 +1,16 @@
//------------------------------------------------------------------------------
// <copyright file="ResolveNameEventHandler.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Security.Permissions;
/// <devdoc>
/// This delegate is used to resolve object names when performing
/// serialization and deserialization.
/// </devdoc>
[HostProtection(SharedState = true)]
public delegate void ResolveNameEventHandler(object sender, ResolveNameEventArgs e);
}

View File

@@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
// <copyright file="RootDesignerSerializerAttribute.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Security.Permissions;
/// <devdoc>
/// This attribute can be placed on a class to indicate what serialization
/// object should be used to serialize the class at design time if it is
/// being used as a root object.
/// </devdoc>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
[Obsolete("This attribute has been deprecated. Use DesignerSerializerAttribute instead. For example, to specify a root designer for CodeDom, use DesignerSerializerAttribute(...,typeof(TypeCodeDomSerializer)). http://go.microsoft.com/fwlink/?linkid=14202")]
public sealed class RootDesignerSerializerAttribute : Attribute {
private bool reloadable;
private string serializerTypeName;
private string serializerBaseTypeName;
private string typeId;
/// <devdoc>
/// Creates a new designer serialization attribute.
/// </devdoc>
public RootDesignerSerializerAttribute(Type serializerType, Type baseSerializerType, bool reloadable) {
this.serializerTypeName = serializerType.AssemblyQualifiedName;
this.serializerBaseTypeName = baseSerializerType.AssemblyQualifiedName;
this.reloadable = reloadable;
}
/// <devdoc>
/// Creates a new designer serialization attribute.
/// </devdoc>
public RootDesignerSerializerAttribute(string serializerTypeName, Type baseSerializerType, bool reloadable) {
this.serializerTypeName = serializerTypeName;
this.serializerBaseTypeName = baseSerializerType.AssemblyQualifiedName;
this.reloadable = reloadable;
}
/// <devdoc>
/// Creates a new designer serialization attribute.
/// </devdoc>
public RootDesignerSerializerAttribute(string serializerTypeName, string baseSerializerTypeName, bool reloadable) {
this.serializerTypeName = serializerTypeName;
this.serializerBaseTypeName = baseSerializerTypeName;
this.reloadable = reloadable;
}
/// <devdoc>
/// Indicates that this root serializer supports reloading. If false, the design document
/// will not automatically perform a reload on behalf of the user. It will be the user's
/// responsibility to reload the document themselves.
/// </devdoc>
public bool Reloadable {
get {
return reloadable;
}
}
/// <devdoc>
/// Retrieves the fully qualified type name of the serializer.
/// </devdoc>
public string SerializerTypeName {
get {
return serializerTypeName;
}
}
/// <devdoc>
/// Retrieves the fully qualified type name of the serializer base type.
/// </devdoc>
public string SerializerBaseTypeName {
get {
return serializerBaseTypeName;
}
}
/// <internalonly/>
/// <devdoc>
/// <para>
/// This defines a unique ID for this attribute type. It is used
/// by filtering algorithms to identify two attributes that are
/// the same type. For most attributes, this just returns the
/// Type instance for the attribute. EditorAttribute overrides
/// this to include the type of the editor base type.
/// </para>
/// </devdoc>
public override object TypeId {
get {
if (typeId == null) {
string baseType = serializerBaseTypeName;
int comma = baseType.IndexOf(',');
if (comma != -1) {
baseType = baseType.Substring(0, comma);
}
typeId = GetType().FullName + baseType;
}
return typeId;
}
}
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <copyright file="SerializationStore.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.ComponentModel.Design.Serialization {
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Security.Permissions;
/// <devdoc>
/// The SerializationStore class is an implementation-specific class that stores
/// serialization data for the component serialization service. The
/// service adds state to this serialization store. Once the store is
/// closed it can be saved to a stream. A serialization store can be
/// deserialized at a later date by the same type of serialization service.
/// SerializationStore implements the IDisposable interface such that Dispose
/// simply calls the Close method. Dispose is implemented as a private
/// interface to avoid confusion. The IDisposable pattern is provided
/// for languages that support a "using" syntax like C# and VB .NET.
/// </devdoc>
[HostProtection(SharedState = true)]
public abstract class SerializationStore : IDisposable
{
/// <devdoc>
/// If there were errors generated during serialization or deserialization of the store, they will be
/// added to this collection.
/// </devdoc>
public abstract ICollection Errors { get; }
/// <devdoc>
/// The Close method closes this store and prevents any objects
/// from being serialized into it. Once closed, the serialization store may be saved.
/// </devdoc>
public abstract void Close();
/// <devdoc>
/// The Save method saves the store to the given stream. If the store
/// is open, Save will automatically close it for you. You
/// can call save as many times as you wish to save the store
/// to different streams.
/// </devdoc>
public abstract void Save(Stream stream);
/// <devdoc>
/// Disposes this object by calling the Close method.
/// </devdoc>
void IDisposable.Dispose() {Dispose(true);}
protected virtual void Dispose(bool disposing) {
if(disposing) Close();
}
}
}