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
- ThreadSafeList.cs
- InputProcessorProfilesLoader.cs
- ToolStripItemImageRenderEventArgs.cs
- DeferredElementTreeState.cs
- ScalarType.cs
- DataAdapter.cs
- Screen.cs
- ThrowHelper.cs
- CommonProperties.cs
- Convert.cs
- FixedSOMTableCell.cs
- BrushMappingModeValidation.cs
- IOException.cs
- SettingsBindableAttribute.cs
- XamlHostingSection.cs
- WindowsNonControl.cs
- Hash.cs
- SerializationSectionGroup.cs
- StringFormat.cs
- TextBlock.cs
- ThumbAutomationPeer.cs
- SByteStorage.cs
- CheckedListBox.cs
- DurableTimerExtension.cs
- SubMenuStyleCollection.cs
- UITypeEditor.cs
- DataControlField.cs
- COM2PictureConverter.cs
- XmlChildNodes.cs
- CatalogPart.cs
- ResXResourceSet.cs
- QueryOutputWriter.cs
- XmlSignificantWhitespace.cs
- X509InitiatorCertificateServiceElement.cs
- ToolStripCustomTypeDescriptor.cs
- RemoteWebConfigurationHost.cs
- AndMessageFilter.cs
- DataSet.cs
- CharacterHit.cs
- UnknownBitmapDecoder.cs
- codemethodreferenceexpression.cs
- PackageStore.cs
- Material.cs
- LocalizabilityAttribute.cs
- XPathSelfQuery.cs
- XmlNodeList.cs
- DrawingVisualDrawingContext.cs
- CheckBoxStandardAdapter.cs
- QueryContinueDragEvent.cs
- Speller.cs
- PropertyItem.cs
- IndependentlyAnimatedPropertyMetadata.cs
- DataGridTextBoxColumn.cs
- xmlfixedPageInfo.cs
- SoapAttributes.cs
- DataGridCellsPanel.cs
- TemplateApplicationHelper.cs
- TypeLibConverter.cs
- TransformConverter.cs
- HttpCapabilitiesSectionHandler.cs
- CaseCqlBlock.cs
- WebPartEditorApplyVerb.cs
- Scripts.cs
- StrokeCollectionDefaultValueFactory.cs
- LoginView.cs
- SafeEventLogReadHandle.cs
- Expression.cs
- FixedDocumentSequencePaginator.cs
- RawStylusInputReport.cs
- CompilerResults.cs
- PolyLineSegment.cs
- ZipIOExtraFieldZip64Element.cs
- EndPoint.cs
- ListViewDeletedEventArgs.cs
- XmlCharacterData.cs
- RoutedUICommand.cs
- SlipBehavior.cs
- BufferModesCollection.cs
- LinearGradientBrush.cs
- AuthenticationServiceManager.cs
- MatrixAnimationUsingKeyFrames.cs
- initElementDictionary.cs
- FileUtil.cs
- FormatterConverter.cs
- CaseStatementSlot.cs
- WebPartsPersonalizationAuthorization.cs
- ParenthesizePropertyNameAttribute.cs
- IsolatedStorageException.cs
- EntityDataSourceEntityTypeFilterItem.cs
- WorkflowRuntimeServiceElementCollection.cs
- NCryptSafeHandles.cs
- EntityConnection.cs
- ProxyFragment.cs
- Roles.cs
- Timer.cs
- Binding.cs
- StreamingContext.cs
- ProcessThreadCollection.cs
- ChannelEndpointElementCollection.cs
- SimpleBitVector32.cs