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
- DefaultPropertiesToSend.cs
- ExcludeFromCodeCoverageAttribute.cs
- Metafile.cs
- ContentValidator.cs
- ShadowGlyph.cs
- LeftCellWrapper.cs
- FormatVersion.cs
- IncrementalHitTester.cs
- Identifier.cs
- BinaryMessageEncodingBindingElement.cs
- NonSerializedAttribute.cs
- DbProviderFactories.cs
- ThemeConfigurationDialog.cs
- CqlBlock.cs
- EmptyEnumerator.cs
- FaultReason.cs
- PrintDialog.cs
- XDRSchema.cs
- DataSysAttribute.cs
- NativeMethods.cs
- WebPartCatalogAddVerb.cs
- HybridDictionary.cs
- Label.cs
- HttpWebRequestElement.cs
- VisualTreeHelper.cs
- ToolStrip.cs
- EventHandlerList.cs
- DeadCharTextComposition.cs
- HighContrastHelper.cs
- Decoder.cs
- WebRequestModuleElement.cs
- TcpStreams.cs
- DecimalConstantAttribute.cs
- RecommendedAsConfigurableAttribute.cs
- CqlIdentifiers.cs
- FixedSOMLineCollection.cs
- HashAlgorithm.cs
- FixedSchema.cs
- AudioFormatConverter.cs
- InternalConfigHost.cs
- EmptyTextWriter.cs
- ResourceSetExpression.cs
- DataBindingExpressionBuilder.cs
- FunctionParameter.cs
- ForeignKeyConstraint.cs
- MessageQueuePermissionEntryCollection.cs
- ApplicationManager.cs
- HttpCapabilitiesSectionHandler.cs
- RemotingAttributes.cs
- ObjectConverter.cs
- TiffBitmapEncoder.cs
- MarshalByRefObject.cs
- TreeNodeStyleCollection.cs
- IndexedString.cs
- DataGridViewAdvancedBorderStyle.cs
- LineServicesCallbacks.cs
- IResourceProvider.cs
- HtmlProps.cs
- KeyGesture.cs
- ConfigurationLockCollection.cs
- BinHexEncoder.cs
- Rijndael.cs
- validationstate.cs
- NetMsmqSecurity.cs
- InputLanguageManager.cs
- Int32AnimationUsingKeyFrames.cs
- GradientStop.cs
- UiaCoreTypesApi.cs
- AudioLevelUpdatedEventArgs.cs
- InvalidProgramException.cs
- NullableDecimalMinMaxAggregationOperator.cs
- BitStack.cs
- OLEDB_Util.cs
- LogWriteRestartAreaAsyncResult.cs
- PauseStoryboard.cs
- FontClient.cs
- ToolStripManager.cs
- TreeWalker.cs
- PageFunction.cs
- MarshalDirectiveException.cs
- KeyGestureValueSerializer.cs
- WebControlAdapter.cs
- ImageButton.cs
- ExitEventArgs.cs
- CompatibleIComparer.cs
- BooleanAnimationUsingKeyFrames.cs
- PrintPageEvent.cs
- TreeWalkHelper.cs
- XmlnsDefinitionAttribute.cs
- sqlser.cs
- RegistrationServices.cs
- UniqueConstraint.cs
- SmtpTransport.cs
- ContentControl.cs
- FormViewRow.cs
- OutputWindow.cs
- MimeWriter.cs
- WebServiceBindingAttribute.cs
- NameTable.cs
- KeyValuePairs.cs