e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
250 lines
7.9 KiB
C#
250 lines
7.9 KiB
C#
//-----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace System.Activities
|
|
{
|
|
using System;
|
|
using System.Activities.Expressions;
|
|
using System.Activities.Runtime;
|
|
using System.Activities.XamlIntegration;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime;
|
|
using System.Windows.Markup;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
public abstract class InArgument : Argument
|
|
{
|
|
internal InArgument()
|
|
: base()
|
|
{
|
|
this.Direction = ArgumentDirection.In;
|
|
}
|
|
|
|
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.ConsiderPassingBaseTypesAsParameters,
|
|
Justification = "Subclass needed to enforce rules about which directions can be referenced.")]
|
|
public static InArgument CreateReference(InArgument argumentToReference, string referencedArgumentName)
|
|
{
|
|
if (argumentToReference == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("argumentToReference");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(referencedArgumentName))
|
|
{
|
|
throw FxTrace.Exception.ArgumentNullOrEmpty("referencedArgumentName");
|
|
}
|
|
|
|
return (InArgument)ActivityUtilities.CreateReferenceArgument(argumentToReference.ArgumentType, ArgumentDirection.In, referencedArgumentName);
|
|
}
|
|
|
|
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.ConsiderPassingBaseTypesAsParameters,
|
|
Justification = "Subclass needed to enforce rules about which directions can be referenced.")]
|
|
public static InArgument CreateReference(InOutArgument argumentToReference, string referencedArgumentName)
|
|
{
|
|
if (argumentToReference == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("argumentToReference");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(referencedArgumentName))
|
|
{
|
|
throw FxTrace.Exception.ArgumentNullOrEmpty("referencedArgumentName");
|
|
}
|
|
|
|
// Note that we explicitly pass In since we want an InArgument created
|
|
return (InArgument)ActivityUtilities.CreateReferenceArgument(argumentToReference.ArgumentType, ArgumentDirection.In, referencedArgumentName);
|
|
}
|
|
}
|
|
|
|
[ContentProperty("Expression")]
|
|
[TypeConverter(typeof(InArgumentConverter))]
|
|
[ValueSerializer(typeof(ArgumentValueSerializer))]
|
|
public sealed class InArgument<T> : InArgument
|
|
{
|
|
public InArgument(Variable variable)
|
|
: this()
|
|
{
|
|
if (variable != null)
|
|
{
|
|
this.Expression = new VariableValue<T> { Variable = variable };
|
|
}
|
|
}
|
|
|
|
public InArgument(DelegateArgument delegateArgument)
|
|
: this()
|
|
{
|
|
if (delegateArgument != null)
|
|
{
|
|
this.Expression = new DelegateArgumentValue<T> { DelegateArgument = delegateArgument };
|
|
}
|
|
}
|
|
|
|
public InArgument(T constValue)
|
|
: this()
|
|
{
|
|
this.Expression = new Literal<T> { Value = constValue };
|
|
}
|
|
|
|
public InArgument(Expression<Func<ActivityContext, T>> expression)
|
|
: this()
|
|
{
|
|
if (expression != null)
|
|
{
|
|
this.Expression = new LambdaValue<T>(expression);
|
|
}
|
|
}
|
|
|
|
public InArgument(Activity<T> expression)
|
|
: this()
|
|
{
|
|
this.Expression = expression;
|
|
}
|
|
|
|
|
|
public InArgument()
|
|
: base()
|
|
{
|
|
this.ArgumentType = typeof(T);
|
|
}
|
|
|
|
[DefaultValue(null)]
|
|
public new Activity<T> Expression
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
internal override ActivityWithResult ExpressionCore
|
|
{
|
|
get
|
|
{
|
|
return this.Expression;
|
|
}
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
this.Expression = null;
|
|
return;
|
|
}
|
|
|
|
if (value is Activity<T>)
|
|
{
|
|
this.Expression = (Activity<T>)value;
|
|
}
|
|
else
|
|
{
|
|
// We do not verify compatibility here. We will do that
|
|
// during CacheMetadata in Argument.Validate.
|
|
this.Expression = new ActivityWithResultWrapper<T>(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static implicit operator InArgument<T>(Variable variable)
|
|
{
|
|
return FromVariable(variable);
|
|
}
|
|
|
|
public static implicit operator InArgument<T>(DelegateArgument delegateArgument)
|
|
{
|
|
return FromDelegateArgument(delegateArgument);
|
|
}
|
|
|
|
public static implicit operator InArgument<T>(Activity<T> expression)
|
|
{
|
|
return FromExpression(expression);
|
|
}
|
|
|
|
public static implicit operator InArgument<T>(T constValue)
|
|
{
|
|
return FromValue(constValue);
|
|
}
|
|
|
|
public static InArgument<T> FromVariable(Variable variable)
|
|
{
|
|
if (variable == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("variable");
|
|
}
|
|
return new InArgument<T>(variable);
|
|
}
|
|
|
|
public static InArgument<T> FromDelegateArgument(DelegateArgument delegateArgument)
|
|
{
|
|
if (delegateArgument == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("delegateArgument");
|
|
}
|
|
return new InArgument<T>(delegateArgument);
|
|
}
|
|
|
|
public static InArgument<T> FromExpression(Activity<T> expression)
|
|
{
|
|
if (expression == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("expression");
|
|
}
|
|
|
|
return new InArgument<T>(expression);
|
|
}
|
|
|
|
public static InArgument<T> FromValue(T constValue)
|
|
{
|
|
return new InArgument<T>
|
|
{
|
|
Expression = new Literal<T> { Value = constValue }
|
|
};
|
|
}
|
|
|
|
// Soft-Link: This method is referenced through reflection by
|
|
// ExpressionUtilities.TryRewriteLambdaExpression. Update that
|
|
// file if the signature changes.
|
|
public new T Get(ActivityContext context)
|
|
{
|
|
return Get<T>(context);
|
|
}
|
|
|
|
public void Set(ActivityContext context, T value)
|
|
{
|
|
if (context == null)
|
|
{
|
|
throw FxTrace.Exception.ArgumentNull("context");
|
|
}
|
|
|
|
context.SetValue(this, value);
|
|
}
|
|
|
|
internal override Location CreateDefaultLocation()
|
|
{
|
|
return Argument.CreateLocation<T>();
|
|
}
|
|
|
|
internal override bool TryPopulateValue(LocationEnvironment targetEnvironment, ActivityInstance activityInstance, ActivityExecutor executor)
|
|
{
|
|
Fx.Assert(this.Expression != null, "This should only be called for non-empty bindings");
|
|
|
|
Location<T> location = Argument.CreateLocation<T>();
|
|
targetEnvironment.Declare(this.RuntimeArgument, location, activityInstance);
|
|
|
|
if (this.Expression.UseOldFastPath)
|
|
{
|
|
location.Value = executor.ExecuteInResolutionContext<T>(activityInstance, this.Expression);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal override void Declare(LocationEnvironment targetEnvironment, ActivityInstance targetActivityInstance)
|
|
{
|
|
targetEnvironment.Declare(this.RuntimeArgument, CreateDefaultLocation(), targetActivityInstance);
|
|
}
|
|
}
|
|
}
|