Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / System / Activities / Statements / InteropEnvironment.cs / 1305376 / InteropEnvironment.cs
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Statements
{
using System.Activities;
using System.Activities.Tracking;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;
using System.Transactions;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Tracking;
using System.Runtime;
using System.Globalization;
class InteropEnvironment : IDisposable, IServiceProvider
{
static readonly ReadOnlyCollection emptyList = new ReadOnlyCollection(new IComparable[] { });
static MethodInfo getServiceMethod = typeof(NativeActivityContext).GetMethod("GetExtension");
NativeActivityContext nativeActivityContext;
BookmarkCallback bookmarkCallback;
bool disposed;
bool completed;
bool canceled;
InteropExecutor executor;
IEnumerable initialBookmarks;
Exception uncaughtException;
Transaction transaction;
public InteropEnvironment(InteropExecutor interopExecutor, NativeActivityContext nativeActivityContext,
BookmarkCallback bookmarkCallback, Interop activity, Transaction transaction)
{
//setup environment;
this.executor = interopExecutor;
this.nativeActivityContext = nativeActivityContext;
this.Activity = activity;
this.executor.ServiceProvider = this;
this.bookmarkCallback = bookmarkCallback;
this.transaction = transaction;
OnEnter();
}
public Interop Activity { get; set; }
void IDisposable.Dispose()
{
if (!this.disposed)
{
OnExit();
this.disposed = true;
}
}
public void Execute(System.Workflow.ComponentModel.Activity definition, NativeActivityContext context)
{
Debug.Assert(!disposed, "Cannot access disposed object");
try
{
this.executor.Initialize(definition, this.Activity.GetInputArgumentValues(context), this.Activity.HasNameCollision);
ProcessExecutionStatus(this.executor.Execute());
}
catch (Exception e)
{
this.uncaughtException = e;
throw;
}
}
public void Cancel()
{
Debug.Assert(!disposed, "Cannot access disposed object");
try
{
ProcessExecutionStatus(this.executor.Cancel());
this.canceled = true;
}
catch (Exception e)
{
this.uncaughtException = e;
throw;
}
}
public void EnqueueEvent(IComparable queueName, object item)
{
Debug.Assert(!disposed, "Cannot access disposed object");
try
{
ProcessExecutionStatus(this.executor.EnqueueEvent(queueName, item));
}
catch (Exception e)
{
this.uncaughtException = e;
throw;
}
}
public void TrackActivityStatusChange(System.Workflow.ComponentModel.Activity activity, int eventCounter)
{
this.nativeActivityContext.Track(
new InteropTrackingRecord(this.Activity.DisplayName,
new ActivityTrackingRecord(
activity.GetType(),
activity.QualifiedName,
activity.ContextGuid,
activity.Parent == null ? Guid.Empty : activity.Parent.ContextGuid,
activity.ExecutionStatus,
DateTime.UtcNow,
eventCounter,
null
)
)
);
}
public void TrackData(System.Workflow.ComponentModel.Activity activity, int eventCounter, string key, object data)
{
this.nativeActivityContext.Track(
new InteropTrackingRecord(this.Activity.DisplayName,
new UserTrackingRecord(
activity.GetType(),
activity.QualifiedName,
activity.ContextGuid,
activity.Parent == null ? Guid.Empty : activity.Parent.ContextGuid,
DateTime.UtcNow,
eventCounter,
key,
data
)
)
);
}
public void Resume()
{
Debug.Assert(!disposed, "Cannot access disposed object");
try
{
ProcessExecutionStatus(this.executor.Resume());
}
catch (Exception e)
{
this.uncaughtException = e;
throw;
}
}
//
object IServiceProvider.GetService(Type serviceType)
{
Debug.Assert(!disposed, "Cannot access disposed object");
MethodInfo genericMethodInfo = getServiceMethod.MakeGenericMethod(serviceType);
return genericMethodInfo.Invoke(this.nativeActivityContext, null);
}
public void Persist()
{
this.Activity.Persist(this.nativeActivityContext);
}
public void CreateTransaction(TransactionOptions transactionOptions)
{
this.Activity.CreateTransaction(this.nativeActivityContext, transactionOptions);
}
public void CommitTransaction()
{
this.Activity.CommitTransaction(this.nativeActivityContext);
}
public void AddResourceManager(VolatileResourceManager resourceManager)
{
this.Activity.AddResourceManager(this.nativeActivityContext,resourceManager);
}
//Called everytime on enter of interopenvironment.
void OnEnter()
{
//Capture Current state of Queues in InteropEnvironment.
this.initialBookmarks = this.executor.Queues;
// This method sets up the ambient transaction for the current thread.
// Since the runtime can execute us on different threads,
// we have to set up the transaction scope everytime we enter the interop environment and clear it when we leave the environment.
this.executor.SetAmbientTransactionAndServiceEnvironment(this.transaction);
}
//Called everytime we leave InteropEnvironment.
void OnExit()
{
if (this.uncaughtException != null)
{
if (WorkflowExecutor.IsIrrecoverableException(this.uncaughtException))
{
return;
}
}
// This method clears the ambient transaction for the current thread.
// Since the runtime can execute us on different threads,
// we have to set up the transaction scope everytime we enter the interop environment and clear it when we leave the environment.
this.executor.ClearAmbientTransactionAndServiceEnvironment();
//Capture Current state of Queues in InteropEnvironment.
IEnumerable currentBookmarks = this.executor.Queues;
//Set outparameters when completed or faulted.
if (this.completed || this.uncaughtException != null)
{
this.Activity.OnClose(this.nativeActivityContext, this.uncaughtException);
this.Activity.SetOutputArgumentValues(
this.executor.Outputs, this.nativeActivityContext);
this.nativeActivityContext.RemoveAllBookmarks();
this.executor.BookmarkQueueMap.Clear();
if (this.canceled)
{
this.nativeActivityContext.MarkCanceled();
}
}
else
{
//Find Differentials
IList deletedBookmarks = new List();
foreach (IComparable value in this.initialBookmarks)
{
deletedBookmarks.Add(value);
}
IList newBookmarks = null;
foreach (IComparable value in currentBookmarks)
{
if (!deletedBookmarks.Remove(value))
{
if (newBookmarks == null)
{
newBookmarks = new List();
}
newBookmarks.Add(value);
}
}
if (newBookmarks != null)
{
// Create new Queues as Bookmark.
foreach (IComparable bookmark in newBookmarks)
{
//
Bookmark v2Bookmark = this.nativeActivityContext.CreateBookmark(bookmark.ToString(),
this.bookmarkCallback, BookmarkOptions.MultipleResume);
this.executor.BookmarkQueueMap.Add(v2Bookmark, bookmark);
}
}
// Delete removed queues.
foreach (IComparable bookmark in deletedBookmarks)
{
this.nativeActivityContext.RemoveBookmark(bookmark.ToString());
List bookmarksToRemove = new List();
foreach (KeyValuePair entry in this.executor.BookmarkQueueMap)
{
if (entry.Value == bookmark)
{
bookmarksToRemove.Add(entry.Key);
}
}
foreach (Bookmark bookmarkToRemove in bookmarksToRemove)
{
this.executor.BookmarkQueueMap.Remove(bookmarkToRemove);
}
}
}
}
void ProcessExecutionStatus(System.Workflow.ComponentModel.ActivityExecutionStatus executionStatus)
{
this.completed = (executionStatus == System.Workflow.ComponentModel.ActivityExecutionStatus.Closed);
}
public static class ParameterHelper
{
static readonly Type activityType = typeof(System.Workflow.ComponentModel.Activity);
static readonly Type compositeActivityType = typeof(System.Workflow.ComponentModel.CompositeActivity);
static readonly Type dependencyObjectType = typeof(System.Workflow.ComponentModel.DependencyObject);
static readonly Type activityConditionType = typeof(System.Workflow.ComponentModel.ActivityCondition);
// Interop Property Names
internal const string interopPropertyActivityType = "ActivityType";
internal const string interopPropertyActivityProperties = "ActivityProperties";
internal const string interopPropertyActivityMetaProperties = "ActivityMetaProperties";
// Allowed Meta-Properties
internal const string activityNameMetaProperty = "Name";
//Check property names for any Property/PropertyOut pairs that would conflict with our naming scheme
public static bool HasPropertyNameCollision(IList properties)
{
bool hasNameCollision = false;
HashSet propertyNames = new HashSet();
foreach (PropertyInfo propertyInfo in properties)
{
propertyNames.Add(propertyInfo.Name);
}
if (propertyNames.Contains(interopPropertyActivityType) ||
propertyNames.Contains(interopPropertyActivityProperties) ||
propertyNames.Contains(interopPropertyActivityMetaProperties))
{
hasNameCollision = true;
}
else
{
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyNames.Contains(propertyInfo.Name + Interop.OutArgumentSuffix))
{
hasNameCollision = true;
break;
}
}
}
return hasNameCollision;
}
public static bool IsBindable(PropertyInfo propertyInfo)
{
bool isMetaProperty;
if (!IsBindableOrMetaProperty(propertyInfo, out isMetaProperty))
{
return false;
}
return !isMetaProperty;
}
public static bool IsBindableOrMetaProperty(PropertyInfo propertyInfo, out bool isMetaProperty)
{
isMetaProperty = false;
// Validate the declaring type: CompositeActivity and DependencyObject
if (propertyInfo.DeclaringType.Equals(compositeActivityType) ||
propertyInfo.DeclaringType.Equals(dependencyObjectType))
{
return false;
}
// Validate the declaring type: Activity
// We allow certain meta-properties on System.Workflow.ComponentModel.Activity to be visible
if (propertyInfo.DeclaringType.Equals(activityType) &&
!String.Equals(propertyInfo.Name, activityNameMetaProperty, StringComparison.Ordinal))
{
return false;
}
//Validate the data type
if (activityConditionType.IsAssignableFrom(propertyInfo.PropertyType))
{
return false;
}
//Validate whether there is DP(Meta) backup
string dependencyPropertyName = propertyInfo.Name;
System.Workflow.ComponentModel.DependencyProperty dependencyProperty = System.Workflow.ComponentModel.DependencyProperty.FromName(dependencyPropertyName,
propertyInfo.DeclaringType);
if (dependencyProperty != null && dependencyProperty.DefaultMetadata.IsMetaProperty)
{
isMetaProperty = true;
}
return true;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SqlCacheDependencySection.cs
- Int16AnimationBase.cs
- ScriptManagerProxy.cs
- SafeEventLogWriteHandle.cs
- RtType.cs
- Processor.cs
- GridViewPageEventArgs.cs
- updatecommandorderer.cs
- RenderOptions.cs
- SortedDictionary.cs
- MemberPath.cs
- CodeLinePragma.cs
- DataGridViewRowCollection.cs
- StorageAssociationTypeMapping.cs
- EntityContainer.cs
- ListViewTableRow.cs
- PersistChildrenAttribute.cs
- GACMembershipCondition.cs
- ContentDesigner.cs
- Themes.cs
- GeneralTransform.cs
- TiffBitmapDecoder.cs
- GenericRootAutomationPeer.cs
- ButtonChrome.cs
- SmiRequestExecutor.cs
- GZipStream.cs
- LingerOption.cs
- SessionEndingCancelEventArgs.cs
- TreeViewImageIndexConverter.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- BulletDecorator.cs
- ConstructorNeedsTagAttribute.cs
- Emitter.cs
- HttpListenerException.cs
- FormViewDeleteEventArgs.cs
- ListViewUpdatedEventArgs.cs
- OpenTypeLayout.cs
- ProcessInputEventArgs.cs
- MatrixAnimationUsingPath.cs
- webeventbuffer.cs
- DefaultValueAttribute.cs
- Guid.cs
- TPLETWProvider.cs
- _RequestCacheProtocol.cs
- DaylightTime.cs
- PublisherMembershipCondition.cs
- WebBrowser.cs
- System.Data_BID.cs
- VolatileEnlistmentState.cs
- TaskScheduler.cs
- ScopedKnownTypes.cs
- UrlMappingsModule.cs
- ipaddressinformationcollection.cs
- VariableAction.cs
- OdbcTransaction.cs
- Expr.cs
- UrlPath.cs
- AsymmetricSignatureFormatter.cs
- ComponentDispatcher.cs
- AuthenticationSection.cs
- PieceDirectory.cs
- GroupDescription.cs
- PageThemeCodeDomTreeGenerator.cs
- PartitionerStatic.cs
- DiscoveryOperationContext.cs
- FactoryMaker.cs
- SqlVisitor.cs
- StreamReader.cs
- DataMisalignedException.cs
- SocketStream.cs
- Paragraph.cs
- WFItemsToSpacerVisibility.cs
- CommandConverter.cs
- RegexRunner.cs
- TypeUtil.cs
- EventToken.cs
- SmtpFailedRecipientsException.cs
- OutputCacheSettingsSection.cs
- SByte.cs
- DynamicValidatorEventArgs.cs
- XmlReflectionImporter.cs
- RecommendedAsConfigurableAttribute.cs
- WebPartHelpVerb.cs
- OutputCacheSettingsSection.cs
- TextStore.cs
- TemplateLookupAction.cs
- DataGridBeginningEditEventArgs.cs
- OleDbErrorCollection.cs
- MessageSecurityVersion.cs
- XmlILOptimizerVisitor.cs
- DebugView.cs
- ContextStack.cs
- ThrowHelper.cs
- XmlProcessingInstruction.cs
- ZipIOModeEnforcingStream.cs
- UniqueEventHelper.cs
- HttpCapabilitiesBase.cs
- BasicHttpSecurity.cs
- AudioSignalProblemOccurredEventArgs.cs
- CompiledQuery.cs