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
- QueryResults.cs
- mediapermission.cs
- ServiceModelExtensionElement.cs
- ProcessModelSection.cs
- DataServiceResponse.cs
- MarshalByValueComponent.cs
- IndexedWhereQueryOperator.cs
- Transform3D.cs
- ellipse.cs
- ADMembershipProvider.cs
- LineInfo.cs
- ApplicationDirectoryMembershipCondition.cs
- MetadataException.cs
- SqlFactory.cs
- ArcSegment.cs
- ValueUtilsSmi.cs
- Polyline.cs
- NetworkInformationPermission.cs
- BitmapImage.cs
- BCLDebug.cs
- Compiler.cs
- ColorPalette.cs
- ContractAdapter.cs
- FileSecurity.cs
- SqlParameterCollection.cs
- ProcessInfo.cs
- MulticastDelegate.cs
- HTTPNotFoundHandler.cs
- Base64Decoder.cs
- LassoHelper.cs
- StringKeyFrameCollection.cs
- TextBoxBase.cs
- TitleStyle.cs
- CompilerParameters.cs
- UnsafeNativeMethodsMilCoreApi.cs
- HttpApplication.cs
- UrlPath.cs
- BufferModesCollection.cs
- Avt.cs
- MaterialCollection.cs
- EventSourceCreationData.cs
- QueryUtil.cs
- RoleGroup.cs
- InternalEnumValidator.cs
- TranslateTransform3D.cs
- XamlTypeMapper.cs
- NullReferenceException.cs
- ScrollContentPresenter.cs
- CollectionViewSource.cs
- SafeSecurityHandles.cs
- XmlTypeAttribute.cs
- ObjectItemNoOpAssemblyLoader.cs
- PointHitTestParameters.cs
- FirstMatchCodeGroup.cs
- ColorTranslator.cs
- SettingsSavedEventArgs.cs
- InnerItemCollectionView.cs
- COSERVERINFO.cs
- StatusBarAutomationPeer.cs
- SqlParameter.cs
- DataSourceCache.cs
- _ServiceNameStore.cs
- WebPartZone.cs
- SendingRequestEventArgs.cs
- OciLobLocator.cs
- X509CertificateChain.cs
- TypeEnumerableViewSchema.cs
- XPathMessageFilter.cs
- GridViewPageEventArgs.cs
- SchemaImporter.cs
- Pipe.cs
- DataKeyArray.cs
- Path.cs
- BehaviorEditorPart.cs
- ChtmlTextWriter.cs
- PhoneCall.cs
- CqlParser.cs
- dataprotectionpermission.cs
- SctClaimSerializer.cs
- ConfigurationLoader.cs
- SqlMethodAttribute.cs
- ArrayList.cs
- BezierSegment.cs
- WebExceptionStatus.cs
- RelatedPropertyManager.cs
- EngineSiteSapi.cs
- OdbcDataAdapter.cs
- CollectionViewGroupInternal.cs
- EdgeProfileValidation.cs
- AsyncStreamReader.cs
- CodeTypeParameter.cs
- MultiSelector.cs
- CallbackHandler.cs
- GeneralTransform3DTo2DTo3D.cs
- DataGridViewCellEventArgs.cs
- Asn1IntegerConverter.cs
- EntityContainerAssociationSet.cs
- AttachedAnnotationChangedEventArgs.cs
- X509AsymmetricSecurityKey.cs
- PathStreamGeometryContext.cs