You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user