Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Serializer / ActivitySurrogate.cs / 1305376 / ActivitySurrogate.cs
namespace System.Workflow.ComponentModel.Serialization { using System; using System.IO; using System.Xml; using System.Reflection; using System.Collections; using System.Diagnostics; using System.Globalization; using System.Collections.Generic; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; internal sealed class ActivitySurrogate : ISerializationSurrogate { public ActivitySurrogate() { } public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) { if (Activity.ContextIdToActivityMap == null) throw new InvalidOperationException(SR.GetString(SR.Error_ActivitySaveLoadNotCalled)); Activity activity = (Activity)obj; bool isSurroundingActivity = false; bool isDanglingActivity = IsDanglingActivity(activity, out isSurroundingActivity); if (isSurroundingActivity) { // if this object is in parent chain then replace it with token if (activity.ContextActivity != null) info.AddValue("cid", activity.ContextId); info.AddValue("id", activity.DottedPath); info.SetType(typeof(ActivityRef)); } else if (!isDanglingActivity) { info.AddValue("id", activity.DottedPath); string[] names = null; MemberInfo[] members = FormatterServicesNoSerializableCheck.GetSerializableMembers(obj.GetType(), out names); object[] memberDatas = FormatterServices.GetObjectData(obj, members); // To improve performance, we specialize the case where there are only 2 fields. One is the // instance dependency property values dictionary and the other is the "disposed" event. if (memberDatas != null && memberDatas.Length == 2) { Debug.Assert(members[0].Name == "dependencyPropertyValues" && members[1].Name == "disposed"); IDictionaryinstanceProperties = (IDictionary )memberDatas[0]; if (instanceProperties != null && instanceProperties.Count > 0) { foreach (KeyValuePair kvp in instanceProperties) { if (kvp.Key != null && !kvp.Key.DefaultMetadata.IsNonSerialized) { info.AddValue("memberData", memberDatas[0]); break; } } } if (memberDatas[1] != null) info.AddValue("disposed", memberDatas[1]); } else { info.AddValue("memberNames", names); info.AddValue("memberDatas", memberDatas); } // for root activity serialize the change actions if there are any if (obj is Activity && ((Activity)obj).Parent == null) { string wMarkup = activity.GetValue(Activity.WorkflowXamlMarkupProperty) as string; if (!string.IsNullOrEmpty(wMarkup)) { info.AddValue("workflowMarkup", wMarkup); //if we got rules in XAML Load case, serialize them as well string rMarkup = activity.GetValue(Activity.WorkflowRulesMarkupProperty) as string; if (!string.IsNullOrEmpty(rMarkup)) info.AddValue("rulesMarkup", rMarkup); } else info.AddValue("type", activity.GetType()); Activity workflowDefinition = (Activity)activity.GetValue(Activity.WorkflowDefinitionProperty); if (workflowDefinition != null) { ArrayList changeActions = (ArrayList)workflowDefinition.GetValue(WorkflowChanges.WorkflowChangeActionsProperty); if (changeActions != null) { Guid changeVersion = (Guid)workflowDefinition.GetValue(WorkflowChanges.WorkflowChangeVersionProperty); info.AddValue("workflowChangeVersion", changeVersion); using (StringWriter changeActionsStringWriter = new StringWriter(CultureInfo.InvariantCulture)) { using (XmlWriter xmlWriter = Design.Helpers.CreateXmlWriter(changeActionsStringWriter)) { new WorkflowMarkupSerializer().Serialize(xmlWriter, changeActions); info.AddValue("workflowChanges", changeActionsStringWriter.ToString()); } } } } } info.SetType(typeof(ActivitySerializedRef)); } else { info.AddValue("id", activity.Name); info.AddValue("type", activity.GetType()); info.SetType(typeof(DanglingActivityRef)); } } public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) { return null; } private bool IsDanglingActivity(Activity activity, out bool isSurrounding) { isSurrounding = false; bool isDangling = false; do { if (Activity.ActivityRoots.Contains(activity)) { isDangling = false; break; } if (activity.Parent == null) { isDangling = ((Activity)Activity.ActivityRoots[0]).RootActivity != activity; break; } if (!activity.Parent.Activities.Contains(activity)) { IList activeContextActivities = null; if (activity.Parent.ContextActivity != null) activeContextActivities = (IList )activity.Parent.ContextActivity.GetValue(Activity.ActiveExecutionContextsProperty); if (activeContextActivities == null || !activeContextActivities.Contains(activity)) { isDangling = true; break; } } activity = activity.Parent; } while (activity != null); isSurrounding = (!isDangling && !Activity.ActivityRoots.Contains(activity)); return isDangling; } [Serializable] private sealed class ActivityRef : IObjectReference { [OptionalField] private int cid = 0; private string id = string.Empty; Object IObjectReference.GetRealObject(StreamingContext context) { if (Activity.ContextIdToActivityMap == null) throw new InvalidOperationException(SR.GetString(SR.Error_ActivitySaveLoadNotCalled)); Activity contextActivity = (Activity)Activity.ContextIdToActivityMap[this.cid]; return contextActivity.TraverseDottedPathFromRoot(this.id); } } [Serializable] private sealed class ActivitySerializedRef : IObjectReference, IDeserializationCallback { private string id = string.Empty; [OptionalField] private object memberData = null; [OptionalField] private object[] memberDatas = null; [OptionalField] private string[] memberNames = null; [OptionalField] private Type type = null; [OptionalField] private string workflowMarkup = null; [OptionalField] private string rulesMarkup = null; [OptionalField] private string workflowChanges = null; [OptionalField] private Guid workflowChangeVersion = Guid.Empty; [OptionalField] private EventHandler disposed = null; [NonSerialized] private Activity cachedDefinitionActivity = null; [NonSerialized] private Activity cachedActivity = null; [NonSerialized] private int lastPosition = 0; object IObjectReference.GetRealObject(StreamingContext context) { // if definition activity has not been yet deserialized then return null if (Activity.DefinitionActivity == null) { if (this.type == null && string.IsNullOrEmpty(this.workflowMarkup)) return null; Activity rootActivityDefinition = null; // We always call into runtime to resolve an activity. The runtime may return an existing cached workflow definition // or it may return a new one if none exists. // When we have dynamic updates, we ask runtime to always return us a new instance of the workflow definition. // This new instance should not be initialized for runtime. We must apply workflow changes first // before we initialize it for runtime. bool createNewDef = (this.workflowChanges != null); rootActivityDefinition = Activity.OnResolveActivityDefinition(this.type, this.workflowMarkup, this.rulesMarkup, createNewDef, !createNewDef, null); if (rootActivityDefinition == null) throw new NullReferenceException(SR.GetString(SR.Error_InvalidRootForWorkflowChanges)); if (createNewDef) { ArrayList changeActions = Activity.OnResolveWorkflowChangeActions(this.workflowChanges, rootActivityDefinition); foreach (WorkflowChangeAction changeAction in changeActions) { bool result = changeAction.ApplyTo(rootActivityDefinition); Debug.Assert(result, "ApplyTo failed"); } rootActivityDefinition.SetValue(WorkflowChanges.WorkflowChangeActionsProperty, changeActions); rootActivityDefinition.SetValue(WorkflowChanges.WorkflowChangeVersionProperty, this.workflowChangeVersion); ((IDependencyObjectAccessor)rootActivityDefinition).InitializeDefinitionForRuntime(null); } // assign it over to the thread static guy so others can access it as well. Activity.DefinitionActivity = rootActivityDefinition; } if (this.cachedActivity == null) { this.cachedDefinitionActivity = Activity.DefinitionActivity.TraverseDottedPathFromRoot(this.id); this.cachedActivity = (Activity)FormatterServices.GetUninitializedObject(this.cachedDefinitionActivity.GetType()); } return this.cachedActivity; } void IDeserializationCallback.OnDeserialization(object sender) { if (this.cachedActivity != null) { bool done = false; string[] currentMemberNames = null; MemberInfo[] members = FormatterServicesNoSerializableCheck.GetSerializableMembers(this.cachedActivity.GetType(), out currentMemberNames); if (members.Length == 2) { Debug.Assert(members[0].Name == "dependencyPropertyValues" && members[1].Name == "disposed"); // To improve performance, we specialize the case where there are only 2 fields. One is the // instance dependency property values dictionary and the other is the "disposed" event. if (this.memberData != null && this.disposed != null) { FormatterServices.PopulateObjectMembers(this.cachedActivity, members, new object[] { this.memberData, this.disposed }); done = true; } else if (this.memberData != null) { FormatterServices.PopulateObjectMembers(this.cachedActivity, new MemberInfo[] { members[0] }, new object[] { this.memberData }); done = true; } else if (this.disposed != null) { FormatterServices.PopulateObjectMembers(this.cachedActivity, new MemberInfo[] { members[1] }, new object[] { this.disposed }); done = true; } } if (!done && this.memberDatas != null) { // re-order the member datas if needed Object[] currentMemberDatas = new object[members.Length]; for( int index = 0; index < currentMemberNames.Length; index++) currentMemberDatas[index] = this.memberDatas[Position(currentMemberNames[index])]; // populate the object FormatterServices.PopulateObjectMembers(this.cachedActivity, members, currentMemberDatas); } this.cachedActivity.FixUpMetaProperties(this.cachedDefinitionActivity); this.cachedActivity = null; } } private int Position(String name) { if (this.memberNames.Length > 0 && this.memberNames[this.lastPosition].Equals(name)) { return this.lastPosition; } else if ((++this.lastPosition < this.memberNames.Length) && (this.memberNames[this.lastPosition].Equals(name))) { return this.lastPosition; } else { // Search for name for (int i = 0; i < this.memberNames.Length; i++) { if (this.memberNames[i].Equals(name)) { this.lastPosition = i; return this.lastPosition; } } //throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_MissingMember"),name,objectType)); this.lastPosition = 0; return -1; } } } [Serializable] private class DanglingActivityRef : IObjectReference { private string id = string.Empty; private Type type = null; [NonSerialized] private Activity activity = null; object IObjectReference.GetRealObject(StreamingContext context) { if (this.activity == null) { // meta properties and other instance properties, parent-child relation ships are lost this.activity = (Activity)Activator.CreateInstance(this.type); this.activity.Name = this.id; } return this.activity; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. namespace System.Workflow.ComponentModel.Serialization { using System; using System.IO; using System.Xml; using System.Reflection; using System.Collections; using System.Diagnostics; using System.Globalization; using System.Collections.Generic; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; internal sealed class ActivitySurrogate : ISerializationSurrogate { public ActivitySurrogate() { } public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) { if (Activity.ContextIdToActivityMap == null) throw new InvalidOperationException(SR.GetString(SR.Error_ActivitySaveLoadNotCalled)); Activity activity = (Activity)obj; bool isSurroundingActivity = false; bool isDanglingActivity = IsDanglingActivity(activity, out isSurroundingActivity); if (isSurroundingActivity) { // if this object is in parent chain then replace it with token if (activity.ContextActivity != null) info.AddValue("cid", activity.ContextId); info.AddValue("id", activity.DottedPath); info.SetType(typeof(ActivityRef)); } else if (!isDanglingActivity) { info.AddValue("id", activity.DottedPath); string[] names = null; MemberInfo[] members = FormatterServicesNoSerializableCheck.GetSerializableMembers(obj.GetType(), out names); object[] memberDatas = FormatterServices.GetObjectData(obj, members); // To improve performance, we specialize the case where there are only 2 fields. One is the // instance dependency property values dictionary and the other is the "disposed" event. if (memberDatas != null && memberDatas.Length == 2) { Debug.Assert(members[0].Name == "dependencyPropertyValues" && members[1].Name == "disposed"); IDictionary instanceProperties = (IDictionary )memberDatas[0]; if (instanceProperties != null && instanceProperties.Count > 0) { foreach (KeyValuePair kvp in instanceProperties) { if (kvp.Key != null && !kvp.Key.DefaultMetadata.IsNonSerialized) { info.AddValue("memberData", memberDatas[0]); break; } } } if (memberDatas[1] != null) info.AddValue("disposed", memberDatas[1]); } else { info.AddValue("memberNames", names); info.AddValue("memberDatas", memberDatas); } // for root activity serialize the change actions if there are any if (obj is Activity && ((Activity)obj).Parent == null) { string wMarkup = activity.GetValue(Activity.WorkflowXamlMarkupProperty) as string; if (!string.IsNullOrEmpty(wMarkup)) { info.AddValue("workflowMarkup", wMarkup); //if we got rules in XAML Load case, serialize them as well string rMarkup = activity.GetValue(Activity.WorkflowRulesMarkupProperty) as string; if (!string.IsNullOrEmpty(rMarkup)) info.AddValue("rulesMarkup", rMarkup); } else info.AddValue("type", activity.GetType()); Activity workflowDefinition = (Activity)activity.GetValue(Activity.WorkflowDefinitionProperty); if (workflowDefinition != null) { ArrayList changeActions = (ArrayList)workflowDefinition.GetValue(WorkflowChanges.WorkflowChangeActionsProperty); if (changeActions != null) { Guid changeVersion = (Guid)workflowDefinition.GetValue(WorkflowChanges.WorkflowChangeVersionProperty); info.AddValue("workflowChangeVersion", changeVersion); using (StringWriter changeActionsStringWriter = new StringWriter(CultureInfo.InvariantCulture)) { using (XmlWriter xmlWriter = Design.Helpers.CreateXmlWriter(changeActionsStringWriter)) { new WorkflowMarkupSerializer().Serialize(xmlWriter, changeActions); info.AddValue("workflowChanges", changeActionsStringWriter.ToString()); } } } } } info.SetType(typeof(ActivitySerializedRef)); } else { info.AddValue("id", activity.Name); info.AddValue("type", activity.GetType()); info.SetType(typeof(DanglingActivityRef)); } } public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) { return null; } private bool IsDanglingActivity(Activity activity, out bool isSurrounding) { isSurrounding = false; bool isDangling = false; do { if (Activity.ActivityRoots.Contains(activity)) { isDangling = false; break; } if (activity.Parent == null) { isDangling = ((Activity)Activity.ActivityRoots[0]).RootActivity != activity; break; } if (!activity.Parent.Activities.Contains(activity)) { IList activeContextActivities = null; if (activity.Parent.ContextActivity != null) activeContextActivities = (IList )activity.Parent.ContextActivity.GetValue(Activity.ActiveExecutionContextsProperty); if (activeContextActivities == null || !activeContextActivities.Contains(activity)) { isDangling = true; break; } } activity = activity.Parent; } while (activity != null); isSurrounding = (!isDangling && !Activity.ActivityRoots.Contains(activity)); return isDangling; } [Serializable] private sealed class ActivityRef : IObjectReference { [OptionalField] private int cid = 0; private string id = string.Empty; Object IObjectReference.GetRealObject(StreamingContext context) { if (Activity.ContextIdToActivityMap == null) throw new InvalidOperationException(SR.GetString(SR.Error_ActivitySaveLoadNotCalled)); Activity contextActivity = (Activity)Activity.ContextIdToActivityMap[this.cid]; return contextActivity.TraverseDottedPathFromRoot(this.id); } } [Serializable] private sealed class ActivitySerializedRef : IObjectReference, IDeserializationCallback { private string id = string.Empty; [OptionalField] private object memberData = null; [OptionalField] private object[] memberDatas = null; [OptionalField] private string[] memberNames = null; [OptionalField] private Type type = null; [OptionalField] private string workflowMarkup = null; [OptionalField] private string rulesMarkup = null; [OptionalField] private string workflowChanges = null; [OptionalField] private Guid workflowChangeVersion = Guid.Empty; [OptionalField] private EventHandler disposed = null; [NonSerialized] private Activity cachedDefinitionActivity = null; [NonSerialized] private Activity cachedActivity = null; [NonSerialized] private int lastPosition = 0; object IObjectReference.GetRealObject(StreamingContext context) { // if definition activity has not been yet deserialized then return null if (Activity.DefinitionActivity == null) { if (this.type == null && string.IsNullOrEmpty(this.workflowMarkup)) return null; Activity rootActivityDefinition = null; // We always call into runtime to resolve an activity. The runtime may return an existing cached workflow definition // or it may return a new one if none exists. // When we have dynamic updates, we ask runtime to always return us a new instance of the workflow definition. // This new instance should not be initialized for runtime. We must apply workflow changes first // before we initialize it for runtime. bool createNewDef = (this.workflowChanges != null); rootActivityDefinition = Activity.OnResolveActivityDefinition(this.type, this.workflowMarkup, this.rulesMarkup, createNewDef, !createNewDef, null); if (rootActivityDefinition == null) throw new NullReferenceException(SR.GetString(SR.Error_InvalidRootForWorkflowChanges)); if (createNewDef) { ArrayList changeActions = Activity.OnResolveWorkflowChangeActions(this.workflowChanges, rootActivityDefinition); foreach (WorkflowChangeAction changeAction in changeActions) { bool result = changeAction.ApplyTo(rootActivityDefinition); Debug.Assert(result, "ApplyTo failed"); } rootActivityDefinition.SetValue(WorkflowChanges.WorkflowChangeActionsProperty, changeActions); rootActivityDefinition.SetValue(WorkflowChanges.WorkflowChangeVersionProperty, this.workflowChangeVersion); ((IDependencyObjectAccessor)rootActivityDefinition).InitializeDefinitionForRuntime(null); } // assign it over to the thread static guy so others can access it as well. Activity.DefinitionActivity = rootActivityDefinition; } if (this.cachedActivity == null) { this.cachedDefinitionActivity = Activity.DefinitionActivity.TraverseDottedPathFromRoot(this.id); this.cachedActivity = (Activity)FormatterServices.GetUninitializedObject(this.cachedDefinitionActivity.GetType()); } return this.cachedActivity; } void IDeserializationCallback.OnDeserialization(object sender) { if (this.cachedActivity != null) { bool done = false; string[] currentMemberNames = null; MemberInfo[] members = FormatterServicesNoSerializableCheck.GetSerializableMembers(this.cachedActivity.GetType(), out currentMemberNames); if (members.Length == 2) { Debug.Assert(members[0].Name == "dependencyPropertyValues" && members[1].Name == "disposed"); // To improve performance, we specialize the case where there are only 2 fields. One is the // instance dependency property values dictionary and the other is the "disposed" event. if (this.memberData != null && this.disposed != null) { FormatterServices.PopulateObjectMembers(this.cachedActivity, members, new object[] { this.memberData, this.disposed }); done = true; } else if (this.memberData != null) { FormatterServices.PopulateObjectMembers(this.cachedActivity, new MemberInfo[] { members[0] }, new object[] { this.memberData }); done = true; } else if (this.disposed != null) { FormatterServices.PopulateObjectMembers(this.cachedActivity, new MemberInfo[] { members[1] }, new object[] { this.disposed }); done = true; } } if (!done && this.memberDatas != null) { // re-order the member datas if needed Object[] currentMemberDatas = new object[members.Length]; for( int index = 0; index < currentMemberNames.Length; index++) currentMemberDatas[index] = this.memberDatas[Position(currentMemberNames[index])]; // populate the object FormatterServices.PopulateObjectMembers(this.cachedActivity, members, currentMemberDatas); } this.cachedActivity.FixUpMetaProperties(this.cachedDefinitionActivity); this.cachedActivity = null; } } private int Position(String name) { if (this.memberNames.Length > 0 && this.memberNames[this.lastPosition].Equals(name)) { return this.lastPosition; } else if ((++this.lastPosition < this.memberNames.Length) && (this.memberNames[this.lastPosition].Equals(name))) { return this.lastPosition; } else { // Search for name for (int i = 0; i < this.memberNames.Length; i++) { if (this.memberNames[i].Equals(name)) { this.lastPosition = i; return this.lastPosition; } } //throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_MissingMember"),name,objectType)); this.lastPosition = 0; return -1; } } } [Serializable] private class DanglingActivityRef : IObjectReference { private string id = string.Empty; private Type type = null; [NonSerialized] private Activity activity = null; object IObjectReference.GetRealObject(StreamingContext context) { if (this.activity == null) { // meta properties and other instance properties, parent-child relation ships are lost this.activity = (Activity)Activator.CreateInstance(this.type); this.activity.Name = this.id; } return this.activity; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MissingSatelliteAssemblyException.cs
- SafeCoTaskMem.cs
- PrintDialog.cs
- TableItemProviderWrapper.cs
- DesignerTransactionCloseEvent.cs
- CodeTypeDeclaration.cs
- ToolBarOverflowPanel.cs
- Emitter.cs
- MapPathBasedVirtualPathProvider.cs
- JournalNavigationScope.cs
- UnsafeNativeMethodsPenimc.cs
- CacheRequest.cs
- Compress.cs
- FixedPageStructure.cs
- MessageFilterTable.cs
- NavigationProgressEventArgs.cs
- OdbcConnectionOpen.cs
- ObjectDataSourceSelectingEventArgs.cs
- ApplicationDirectoryMembershipCondition.cs
- VisualTreeUtils.cs
- Publisher.cs
- StatusBarPanel.cs
- WebPartHeaderCloseVerb.cs
- StaticExtensionConverter.cs
- UnknownBitmapEncoder.cs
- HandlerFactoryWrapper.cs
- SoapTypeAttribute.cs
- CounterSet.cs
- NameValueFileSectionHandler.cs
- SchemaImporter.cs
- ColorConverter.cs
- HttpClientCertificate.cs
- TableCell.cs
- XmlBindingWorker.cs
- RoutedPropertyChangedEventArgs.cs
- Splitter.cs
- UnsafeNetInfoNativeMethods.cs
- CompositeFontFamily.cs
- BitmapEditor.cs
- PathFigureCollectionConverter.cs
- JsonFaultDetail.cs
- remotingproxy.cs
- SmiContext.cs
- ThrowHelper.cs
- ConfigurationStrings.cs
- RadioButtonFlatAdapter.cs
- XpsSerializationManagerAsync.cs
- SqlDependency.cs
- CleanUpVirtualizedItemEventArgs.cs
- FormViewInsertedEventArgs.cs
- SafeNativeMethodsOther.cs
- EncryptedKey.cs
- StrongName.cs
- _ListenerRequestStream.cs
- DataGridTablesFactory.cs
- HttpListenerContext.cs
- Compress.cs
- InProcStateClientManager.cs
- NameValueSectionHandler.cs
- LoginName.cs
- StructuredType.cs
- SettingsAttributeDictionary.cs
- MailSettingsSection.cs
- CharacterMetrics.cs
- KnownAssembliesSet.cs
- Fonts.cs
- SelfIssuedAuthRSAPKCS1SignatureFormatter.cs
- FilterQuery.cs
- OleAutBinder.cs
- TrimSurroundingWhitespaceAttribute.cs
- ValuePattern.cs
- RegistrySecurity.cs
- WorkflowInspectionServices.cs
- DataGridTableStyleMappingNameEditor.cs
- WebReferencesBuildProvider.cs
- StaticContext.cs
- ExternalFile.cs
- DirectoryNotFoundException.cs
- CompressEmulationStream.cs
- ObjectDataSourceStatusEventArgs.cs
- _IPv6Address.cs
- DbConnectionInternal.cs
- EventLogTraceListener.cs
- FlowLayout.cs
- Transform.cs
- KeyFrames.cs
- ActivityTypeCodeDomSerializer.cs
- CharEntityEncoderFallback.cs
- FormViewDeleteEventArgs.cs
- TripleDES.cs
- XmlTextReaderImplHelpers.cs
- ScaleTransform3D.cs
- FormViewInsertEventArgs.cs
- PerfCounterSection.cs
- FacetDescription.cs
- XsltQilFactory.cs
- Keyboard.cs
- InputScope.cs
- InheritablePropertyChangeInfo.cs
- FrugalList.cs