Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / RuntimeArgument.cs / 1305376 / RuntimeArgument.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.Activities { using System; using System.Activities.Runtime; using System.Activities.Validation; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime; using System.Text; [Fx.Tag.XamlVisible(false)] public sealed class RuntimeArgument : LocationReference { static InternalEvaluationOrderComparer evaluationOrderComparer; Argument boundArgument; PropertyDescriptor bindingProperty; object bindingPropertyOwner; ListoverloadGroupNames; int cacheId; string name; UInt32 nameHash; bool isNameHashSet; Type type; public RuntimeArgument(string name, Type argumentType, ArgumentDirection direction) : this(name, argumentType, direction, false) { } public RuntimeArgument(string name, Type argumentType, ArgumentDirection direction, List overloadGroupNames) : this(name, argumentType, direction, false, overloadGroupNames) { } public RuntimeArgument(string name, Type argumentType, ArgumentDirection direction, bool isRequired) : this(name, argumentType, direction, isRequired, null) { } public RuntimeArgument(string name, Type argumentType, ArgumentDirection direction, bool isRequired, List overloadGroupNames) { if (string.IsNullOrEmpty(name)) { throw FxTrace.Exception.ArgumentNullOrEmpty("name"); } if (argumentType == null) { throw FxTrace.Exception.ArgumentNull("argumentType"); } ArgumentDirectionHelper.Validate(direction, "direction"); this.name = name; this.type = argumentType; this.Direction = direction; this.IsRequired = isRequired; this.overloadGroupNames = overloadGroupNames; } internal RuntimeArgument(string name, Type argumentType, ArgumentDirection direction, bool isRequired, List overloadGroups, PropertyDescriptor bindingProperty, object propertyOwner) : this(name, argumentType, direction, isRequired, overloadGroups) { this.bindingProperty = bindingProperty; this.bindingPropertyOwner = propertyOwner; } internal RuntimeArgument(string name, Type argumentType, ArgumentDirection direction, bool isRequired, List overloadGroups, Argument argument) : this(name, argumentType, direction, isRequired, overloadGroups) { Fx.Assert(argument != null, "This ctor is only for arguments discovered via reflection in an IDictionary and therefore cannot be null."); // Bind straightway since we're not dealing with a property and empty binding isn't an issue. Argument.Bind(argument, this); } internal static IComparer EvaluationOrderComparer { get { if (RuntimeArgument.evaluationOrderComparer == null) { RuntimeArgument.evaluationOrderComparer = new InternalEvaluationOrderComparer(); } return RuntimeArgument.evaluationOrderComparer; } } protected override string NameCore { get { return this.name; } } protected override Type TypeCore { get { return this.type; } } public ArgumentDirection Direction { get; private set; } public bool IsRequired { get; private set; } public ReadOnlyCollection OverloadGroupNames { get { if (this.overloadGroupNames == null) { this.overloadGroupNames = new List (0); } return new ReadOnlyCollection (this.overloadGroupNames); } } internal Activity Owner { get; private set; } internal bool IsInTree { get { return this.Owner != null; } } internal bool IsBound { get { return this.boundArgument != null; } } internal bool IsEvaluationOrderSpecified { get { return this.IsBound && this.BoundArgument.EvaluationOrder != Argument.UnspecifiedEvaluationOrder; } } internal Argument BoundArgument { get { return this.boundArgument; } set { // We allow this to be set an unlimited number of times. We also allow it // to be set back to null. this.boundArgument = value; } } // returns true if this is the "Result" argument of an Activity internal bool IsResult { get { Fx.Assert(this.Owner != null, "should only be called when argument is bound"); return this.Owner.IsResultArgument(this); } } internal void SetupBinding(Activity owningElement, bool createEmptyBinding) { if (this.bindingProperty != null) { Argument argument = (Argument)this.bindingProperty.GetValue(this.bindingPropertyOwner); if (argument == null) { Fx.Assert(this.bindingProperty.PropertyType.IsGenericType, "We only support arguments that are generic types in our reflection walk."); argument = (Argument) Activator.CreateInstance(this.bindingProperty.PropertyType); argument.WasDesignTimeNull = true; if (createEmptyBinding && !this.bindingProperty.IsReadOnly) { this.bindingProperty.SetValue(this.bindingPropertyOwner, argument); } } Argument.Bind(argument, this); } else if (!this.IsBound) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(owningElement); PropertyDescriptor targetProperty = null; for (int i = 0; i < properties.Count; i++) { PropertyDescriptor property = properties[i]; // We only support auto-setting the property // for generic types. Otherwise we have no // guarantee that the argument returned by the // property still matches the runtime argument's // type. if (property.Name == this.Name && property.PropertyType.IsGenericType) { ArgumentDirection direction; Type argumentType; if (ActivityUtilities.TryGetArgumentDirectionAndType(property.PropertyType, out direction, out argumentType)) { if (this.Type == argumentType && this.Direction == direction) { targetProperty = property; break; } } } } Argument argument = null; if (targetProperty != null) { argument = (Argument)targetProperty.GetValue(owningElement); } if (argument == null) { if (targetProperty != null) { if (targetProperty.PropertyType.IsGenericType) { argument = (Argument)Activator.CreateInstance(targetProperty.PropertyType); } else { argument = ActivityUtilities.CreateArgument(this.Type, this.Direction); } } else { argument = ActivityUtilities.CreateArgument(this.Type, this.Direction); } argument.WasDesignTimeNull = true; if (targetProperty != null && createEmptyBinding && !targetProperty.IsReadOnly) { targetProperty.SetValue(owningElement, argument); } } Argument.Bind(argument, this); } Fx.Assert(this.IsBound, "We should always be bound when exiting this method."); } internal bool InitializeRelationship(Activity parent, ref IList validationErrors) { if (this.cacheId == parent.CacheId) { // We're part of the same tree walk if (this.Owner == parent) { ActivityUtilities.Add(ref validationErrors, ProcessViolation(parent, SR.ArgumentIsAddedMoreThanOnce(this.Name, this.Owner.DisplayName))); // Get out early since we've already initialized this argument. return false; } Fx.Assert(this.Owner != null, "We must have already assigned an owner."); ActivityUtilities.Add(ref validationErrors, ProcessViolation(parent, SR.ArgumentAlreadyInUse(this.Name, this.Owner.DisplayName, parent.DisplayName))); // Get out early since we've already initialized this argument. return false; } if (this.boundArgument != null && this.boundArgument.RuntimeArgument != this) { ActivityUtilities.Add(ref validationErrors, ProcessViolation(parent, SR.RuntimeArgumentBindingInvalid(this.Name, this.boundArgument.RuntimeArgument.Name))); return false; } this.Owner = parent; this.cacheId = parent.CacheId; if (this.boundArgument != null) { this.boundArgument.Validate(parent, ref validationErrors); if (!this.BoundArgument.IsEmpty) { return this.BoundArgument.Expression.InitializeRelationship(this, ref validationErrors); } } return true; } internal bool TryPopulateValue(LocationEnvironment targetEnvironment, ActivityInstance targetActivityInstance, ActivityContext resolutionContext, object argumentValueOverride, Location resultLocation, bool skipFastPath) { // We populate values in the following order: // Override // Binding // Default Fx.Assert(this.IsBound, "We should ALWAYS be bound at runtime."); if (argumentValueOverride != null) { Fx.Assert( resultLocation == null, "We should never have both an override and a result location unless some day " + "we decide to allow overrides for argument expressions. If that day comes, we " + "need to deal with potential issues around someone providing and override for " + "a result - with the current code it wouldn't end up in the resultLocation."); Location location = this.boundArgument.CreateDefaultLocation(); targetEnvironment.Declare(this, location, targetActivityInstance); location.Value = argumentValueOverride; return true; } else if (!this.boundArgument.IsEmpty) { if (skipFastPath) { this.BoundArgument.Declare(targetEnvironment, targetActivityInstance); return false; } else { resolutionContext.Activity = this.boundArgument.Expression; return this.boundArgument.TryPopulateValue(targetEnvironment, targetActivityInstance, resolutionContext); } } else if (resultLocation != null && this.IsResult) { targetEnvironment.Declare(this, resultLocation, targetActivityInstance); return true; } else { Location location = this.boundArgument.CreateDefaultLocation(); targetEnvironment.Declare(this, location, targetActivityInstance); return true; } } public override Location GetLocation(ActivityContext context) { if (context == null) { throw FxTrace.Exception.ArgumentNull("context"); } // No need to call context.ThrowIfDisposed explicitly since all // the methods/properties on the context will perform that check. ThrowIfNotInTree(); Location location; if (!context.AllowChainedEnvironmentAccess) { if (!object.ReferenceEquals(this.Owner, context.Activity)) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CanOnlyGetOwnedArguments( context.Activity.DisplayName, this.Name, this.Owner.DisplayName))); } Fx.Assert(object.ReferenceEquals(context.Environment.Definition, context.Activity), "If we get here then these should be equal."); if (!context.Environment.TryGetLocation(this.Id, out location)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ArgumentDoesNotExistInEnvironment(this.Name))); } } else { Fx.Assert(object.ReferenceEquals(this.Owner, context.Activity) || object.ReferenceEquals(this.Owner, context.Activity.MemberOf.Owner), "This should have been validated by the activity which set AllowChainedEnvironmentAccess."); if (!context.Environment.TryGetLocation(this.Id, this.Owner, out location)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ArgumentDoesNotExistInEnvironment(this.Name))); } } return location; } // Soft-Link: This method is referenced through reflection by // ExpressionUtilities.TryRewriteLambdaExpression. Update that // file if the signature changes. public object Get(ActivityContext context) { return context.GetValue
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FileCodeGroup.cs
- ExpressionHelper.cs
- StreamWriter.cs
- DbDataAdapter.cs
- TagPrefixInfo.cs
- PerformanceCounter.cs
- UserPersonalizationStateInfo.cs
- MetadataSerializer.cs
- QualificationDataItem.cs
- StringResourceManager.cs
- BitmapEffectrendercontext.cs
- SchemaImporterExtensionsSection.cs
- CompletionCallbackWrapper.cs
- ToolStripRendererSwitcher.cs
- EventHandlersStore.cs
- CriticalFinalizerObject.cs
- TypeLibConverter.cs
- DefaultSerializationProviderAttribute.cs
- ConvertersCollection.cs
- Module.cs
- FastPropertyAccessor.cs
- Pen.cs
- AutomationPeer.cs
- CollectionBase.cs
- PartitionerQueryOperator.cs
- ServicePointManager.cs
- TextRangeEditLists.cs
- _ChunkParse.cs
- PipelineModuleStepContainer.cs
- InteropEnvironment.cs
- RijndaelManaged.cs
- ToolStripContainer.cs
- XmlValueConverter.cs
- x509utils.cs
- SerializationAttributes.cs
- PropertyItemInternal.cs
- FloatAverageAggregationOperator.cs
- PostBackOptions.cs
- CharacterBuffer.cs
- InputQueue.cs
- HeaderedContentControl.cs
- RuntimeConfig.cs
- AssertUtility.cs
- NumericUpDown.cs
- BufferModeSettings.cs
- Html32TextWriter.cs
- RegularExpressionValidator.cs
- ObjectReferenceStack.cs
- ToolboxDataAttribute.cs
- RtfControlWordInfo.cs
- VirtualPathUtility.cs
- RPIdentityRequirement.cs
- HierarchicalDataTemplate.cs
- XmlName.cs
- FontSourceCollection.cs
- IdentitySection.cs
- RectangleHotSpot.cs
- BCLDebug.cs
- ProcessHostConfigUtils.cs
- Vector3DAnimation.cs
- FileRecordSequence.cs
- PieceDirectory.cs
- XmlSchemaAny.cs
- SocketConnection.cs
- Emitter.cs
- DataGridViewCellValueEventArgs.cs
- DefaultBindingPropertyAttribute.cs
- JsonDeserializer.cs
- PolyBezierSegment.cs
- WmfPlaceableFileHeader.cs
- CacheChildrenQuery.cs
- XmlMemberMapping.cs
- coordinatorscratchpad.cs
- StatusBarPanel.cs
- FileSystemEventArgs.cs
- IgnorePropertiesAttribute.cs
- SafeNativeMethods.cs
- IteratorDescriptor.cs
- NamespaceQuery.cs
- AssemblyUtil.cs
- bidPrivateBase.cs
- AuthorizationSection.cs
- Enlistment.cs
- CachedTypeface.cs
- OrderedDictionary.cs
- List.cs
- BaseTemplateParser.cs
- TableLayoutPanelCellPosition.cs
- SerialStream.cs
- KnownIds.cs
- HMACSHA1.cs
- BuildProvider.cs
- FileSystemInfo.cs
- RowBinding.cs
- FontDialog.cs
- HttpCachePolicy.cs
- DeflateStream.cs
- LoadWorkflowAsyncResult.cs
- PatternMatcher.cs
- XmlSchemaDatatype.cs