|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities
{
using System.Activities.DynamicUpdate;
using System.Activities.Runtime;
using System.Activities.Validation;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.Runtime.Serialization;
public abstract class NativeActivity : Activity, IInstanceUpdatable
{
protected NativeActivity()
: base()
{
}
protected internal sealed override Version ImplementationVersion
{
get
{
return null;
}
set
{
if (value != null)
{
throw FxTrace.Exception.AsError(new NotSupportedException());
}
}
}
[IgnoreDataMember]
[Fx.Tag.KnownXamlExternal]
protected sealed override Func<Activity> Implementation
{
get
{
return null;
}
set
{
if (value != null)
{
throw FxTrace.Exception.AsError(new NotSupportedException());
}
}
}
protected virtual bool CanInduceIdle
{
get
{
return false;
}
}
internal override bool InternalCanInduceIdle
{
get
{
return this.CanInduceIdle;
}
}
protected abstract void Execute(NativeActivityContext context);
protected virtual void Abort(NativeActivityAbortContext context)
{
}
protected virtual void Cancel(NativeActivityContext context)
{
if (!context.IsCancellationRequested)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.DefaultCancelationRequiresCancelHasBeenRequested));
}
context.Cancel();
}
sealed internal override void OnInternalCacheMetadata(bool createEmptyBindings)
{
NativeActivityMetadata metadata = new NativeActivityMetadata(this, GetParentEnvironment(), createEmptyBindings);
CacheMetadata(metadata);
metadata.Dispose();
}
protected sealed override void CacheMetadata(ActivityMetadata metadata)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WrongCacheMetadataForNativeActivity));
}
protected virtual void CacheMetadata(NativeActivityMetadata metadata)
{
ReflectedInformation information = new ReflectedInformation(this);
// We bypass the metadata structure to avoid the checks for null entries
SetArgumentsCollection(information.GetArguments(), metadata.CreateEmptyBindings);
SetChildrenCollection(information.GetChildren());
SetDelegatesCollection(information.GetDelegates());
SetVariablesCollection(information.GetVariables());
}
internal sealed override void OnInternalCreateDynamicUpdateMap(DynamicUpdateMapBuilder.Finalizer finalizer,
DynamicUpdateMapBuilder.IDefinitionMatcher matcher, Activity originalActivity)
{
NativeActivityUpdateMapMetadata metadata = new NativeActivityUpdateMapMetadata(finalizer, matcher, this);
try
{
OnCreateDynamicUpdateMap(metadata, originalActivity);
}
finally
{
metadata.Dispose();
}
}
protected sealed override void OnCreateDynamicUpdateMap(UpdateMapMetadata metadata, Activity originalActivity)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WrongOnCreateDynamicUpdateMapForNativeActivity));
}
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.ConsiderPassingBaseTypesAsParameters,
Justification = "Runtime passes in derived class to make more functionality availble to overriders")]
protected virtual void OnCreateDynamicUpdateMap(NativeActivityUpdateMapMetadata metadata, Activity originalActivity)
{
// default UpdateMapMetadata.AllowUpdateInsideThisActivity is TRUE
if (!metadata.IsUpdateExplicitlyAllowedOrDisallowed && !DoPublicChildrenMatch(metadata, this, originalActivity))
{
metadata.DisallowUpdateInsideThisActivity(SR.PublicChildrenChangeBlockDU);
}
}
internal static bool DoPublicChildrenMatch(UpdateMapMetadata metadata, Activity updatedActivity, Activity originalActivity)
{
return ActivityComparer.ListEquals(updatedActivity.Children, originalActivity.Children, metadata.AreMatch) &&
ActivityComparer.ListEquals(updatedActivity.Delegates, originalActivity.Delegates, metadata.AreMatch) &&
ActivityComparer.ListEquals(updatedActivity.ImportedChildren, originalActivity.ImportedChildren, metadata.AreMatch) &&
ActivityComparer.ListEquals(updatedActivity.ImportedDelegates, originalActivity.ImportedDelegates, metadata.AreMatch);
}
void IInstanceUpdatable.InternalUpdateInstance(NativeActivityUpdateContext updateContext)
{
this.UpdateInstance(updateContext);
}
protected virtual void UpdateInstance(NativeActivityUpdateContext updateContext)
{
// note that this may be called multiple times on this same activity but with different instances
// Override this only if you need to update runtime state as part of a dynamic update.
}
internal override void InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
{
NativeActivityContext context = executor.NativeActivityContextPool.Acquire();
try
{
context.Initialize(instance, executor, bookmarkManager);
Execute(context);
}
finally
{
context.Dispose();
executor.NativeActivityContextPool.Release(context);
}
}
internal override void InternalAbort(ActivityInstance instance, ActivityExecutor executor, Exception terminationReason)
{
NativeActivityAbortContext context = new NativeActivityAbortContext(instance, executor, terminationReason);
try
{
Abort(context);
}
finally
{
context.Dispose();
}
}
internal override void InternalCancel(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
{
NativeActivityContext context = executor.NativeActivityContextPool.Acquire();
try
{
context.Initialize(instance, executor, bookmarkManager);
Cancel(context);
}
finally
{
context.Dispose();
executor.NativeActivityContextPool.Release(context);
}
}
}
public abstract class NativeActivity<TResult> : Activity<TResult>, IInstanceUpdatable
{
protected NativeActivity()
: base()
{
}
protected internal sealed override Version ImplementationVersion
{
get
{
return null;
}
set
{
if (value != null)
{
throw FxTrace.Exception.AsError(new NotSupportedException());
}
}
}
[IgnoreDataMember]
[Fx.Tag.KnownXamlExternal]
protected sealed override Func<Activity> Implementation
{
get
{
return null;
}
set
{
if (value != null)
{
throw FxTrace.Exception.AsError(new NotSupportedException());
}
}
}
protected virtual bool CanInduceIdle
{
get
{
return false;
}
}
internal override bool InternalCanInduceIdle
{
get
{
return this.CanInduceIdle;
}
}
protected abstract void Execute(NativeActivityContext context);
protected virtual void Abort(NativeActivityAbortContext context)
{
}
protected virtual void Cancel(NativeActivityContext context)
{
if (!context.IsCancellationRequested)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.DefaultCancelationRequiresCancelHasBeenRequested));
}
context.Cancel();
}
sealed internal override void OnInternalCacheMetadataExceptResult(bool createEmptyBindings)
{
NativeActivityMetadata metadata = new NativeActivityMetadata(this, GetParentEnvironment(), createEmptyBindings);
CacheMetadata(metadata);
metadata.Dispose();
}
protected sealed override void CacheMetadata(ActivityMetadata metadata)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WrongCacheMetadataForNativeActivity));
}
protected virtual void CacheMetadata(NativeActivityMetadata metadata)
{
ReflectedInformation information = new ReflectedInformation(this);
// We bypass the metadata structure to avoid the checks for null entries
SetArgumentsCollection(information.GetArguments(), metadata.CreateEmptyBindings);
SetChildrenCollection(information.GetChildren());
SetDelegatesCollection(information.GetDelegates());
SetVariablesCollection(information.GetVariables());
}
internal sealed override void OnInternalCreateDynamicUpdateMap(DynamicUpdateMapBuilder.Finalizer finalizer,
DynamicUpdateMapBuilder.IDefinitionMatcher matcher, Activity originalActivity)
{
NativeActivityUpdateMapMetadata metadata = new NativeActivityUpdateMapMetadata(finalizer, matcher, this);
try
{
OnCreateDynamicUpdateMap(metadata, originalActivity);
}
finally
{
metadata.Dispose();
}
}
protected sealed override void OnCreateDynamicUpdateMap(UpdateMapMetadata metadata, Activity originalActivity)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WrongOnCreateDynamicUpdateMapForNativeActivity));
}
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.ConsiderPassingBaseTypesAsParameters,
Justification = "Runtime passes in derived class to make more functionality availble to overriders")]
protected virtual void OnCreateDynamicUpdateMap(NativeActivityUpdateMapMetadata metadata, Activity originalActivity)
{
// default UpdateMapMetadata.AllowUpdateInsideThisActivity is TRUE
if (!metadata.IsUpdateExplicitlyAllowedOrDisallowed && !NativeActivity.DoPublicChildrenMatch(metadata, this, originalActivity))
{
metadata.DisallowUpdateInsideThisActivity(SR.PublicChildrenChangeBlockDU);
}
}
void IInstanceUpdatable.InternalUpdateInstance(NativeActivityUpdateContext updateContext)
{
this.UpdateInstance(updateContext);
}
protected virtual void UpdateInstance(NativeActivityUpdateContext updateContext)
{
// note that this may be called multiple times on this same activity but with different instances
// Override this only if you need to update runtime state as part of a dynamic update.
}
internal override void InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
{
NativeActivityContext context = executor.NativeActivityContextPool.Acquire();
try
{
context.Initialize(instance, executor, bookmarkManager);
Execute(context);
}
finally
{
context.Dispose();
executor.NativeActivityContextPool.Release(context);
}
}
internal override void InternalAbort(ActivityInstance instance, ActivityExecutor executor, Exception terminationReason)
{
NativeActivityAbortContext context = new NativeActivityAbortContext(instance, executor, terminationReason);
try
{
Abort(context);
}
finally
{
context.Dispose();
}
}
internal override void InternalCancel(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
{
NativeActivityContext context = executor.NativeActivityContextPool.Acquire();
try
{
context.Initialize(instance, executor, bookmarkManager);
Cancel(context);
}
finally
{
context.Dispose();
executor.NativeActivityContextPool.Release(context);
}
}
}
}
|