/mcs/class/referencesource/System.Activities/System/Activities/Hosting/SymbolResolver.cs
C# | 424 lines | 340 code | 68 blank | 16 comment | 32 complexity | bb6b29e8c47fcf60692067af2e913267 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.Activities.Hosting
- {
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Runtime;
- [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldHaveCorrectSuffix,
- Justification = "Approved name")]
- public sealed class SymbolResolver : IDictionary<string, object>
- {
- Dictionary<string, ExternalLocationReference> symbols;
- public SymbolResolver()
- {
- this.symbols = new Dictionary<string, ExternalLocationReference>();
- }
- public int Count
- {
- get { return this.symbols.Count; }
- }
- public bool IsReadOnly
- {
- get { return false; }
- }
- public ICollection<string> Keys
- {
- get { return this.symbols.Keys; }
- }
- public ICollection<object> Values
- {
- get
- {
- List<object> values = new List<object>(this.symbols.Count);
- foreach (ExternalLocationReference reference in this.symbols.Values)
- {
- values.Add(reference.Value);
- }
- return values;
- }
- }
- public object this[string key]
- {
- get
- {
- // We don't need to do any existence checks since we want the dictionary exception to bubble up
- return this.symbols[key].Value;
- }
- set
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- this.symbols[key] = CreateReference(key, value);
- }
- }
- public void Add(string key, object value)
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- this.symbols.Add(key, CreateReference(key, value));
- }
- public void Add(string key, Type type)
- {
- if (type == null)
- {
- throw FxTrace.Exception.ArgumentNull("type");
- }
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- this.symbols.Add(key, new ExternalLocationReference(key, type, TypeHelper.GetDefaultValueForType(type)));
- }
- public void Add(string key, object value, Type type)
- {
- if (type == null)
- {
- throw FxTrace.Exception.ArgumentNull("type");
- }
- if (!TypeHelper.AreTypesCompatible(value, type))
- {
- throw FxTrace.Exception.Argument("value", SR.ValueMustBeAssignableToType);
- }
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- this.symbols.Add(key, new ExternalLocationReference(key, type, value));
- }
- ExternalLocationReference CreateReference(string name, object value)
- {
- Type valueType = TypeHelper.ObjectType;
- if (value != null)
- {
- valueType = value.GetType();
- }
- return new ExternalLocationReference(name, valueType, value);
- }
- public void Add(KeyValuePair<string, object> item)
- {
- Add(item.Key, item.Value);
- }
- public void Clear()
- {
- this.symbols.Clear();
- }
- public bool Contains(KeyValuePair<string, object> item)
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- ExternalLocationReference reference;
- if (this.symbols.TryGetValue(item.Key, out reference))
- {
- return item.Value == reference.Value;
- }
- return false;
- }
- public bool ContainsKey(string key)
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- return this.symbols.ContainsKey(key);
- }
- public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
- {
- if (array == null)
- {
- throw FxTrace.Exception.ArgumentNull("array");
- }
- if (arrayIndex < 0)
- {
- throw FxTrace.Exception.ArgumentOutOfRange("arrayIndex", arrayIndex, SR.CopyToIndexOutOfRange);
- }
- if (array.Rank > 1)
- {
- throw FxTrace.Exception.Argument("array", SR.CopyToRankMustBeOne);
- }
- if (this.symbols.Count > array.Length - arrayIndex)
- {
- throw FxTrace.Exception.Argument("array", SR.CopyToNotEnoughSpaceInArray);
- }
- foreach (KeyValuePair<string, ExternalLocationReference> pair in this.symbols)
- {
- Fx.Assert(arrayIndex < array.Length, "We must have room since we validated it.");
- array[arrayIndex] = new KeyValuePair<string, object>(pair.Key, pair.Value.Value);
- arrayIndex++;
- }
- }
- public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
- {
- foreach (KeyValuePair<string, ExternalLocationReference> pair in this.symbols)
- {
- yield return new KeyValuePair<string, object>(pair.Key, pair.Value.Value);
- }
- }
- internal IEnumerable<KeyValuePair<string, LocationReference>> GetLocationReferenceEnumerator()
- {
- foreach (KeyValuePair<string, ExternalLocationReference> pair in this.symbols)
- {
- yield return new KeyValuePair<string, LocationReference>(pair.Key, pair.Value);
- }
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- public bool Remove(string key)
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- return this.symbols.Remove(key);
- }
- public bool Remove(KeyValuePair<string, object> item)
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- ExternalLocationReference reference;
- if (this.symbols.TryGetValue(item.Key, out reference))
- {
- if (reference.Value == item.Value)
- {
- this.symbols.Remove(item.Key);
- return true;
- }
- }
- return false;
- }
- public bool TryGetValue(string key, out object value)
- {
- // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
- ExternalLocationReference reference;
- if (this.symbols.TryGetValue(key, out reference))
- {
- value = reference.Value;
- return true;
- }
- value = null;
- return false;
- }
- internal bool TryGetLocationReference(string name, out LocationReference result)
- {
- ExternalLocationReference reference;
- if (this.symbols.TryGetValue(name, out reference))
- {
- result = reference;
- return true;
- }
- result = null;
- return false;
- }
- internal bool IsVisible(LocationReference locationReference)
- {
- // We only check for null since string.Empty is
- // actually allowed.
- if (locationReference.Name == null)
- {
- return false;
- }
- else
- {
- ExternalLocationReference externalLocationReference;
- if (this.symbols.TryGetValue(locationReference.Name, out externalLocationReference))
- {
- if (externalLocationReference.Type == locationReference.Type)
- {
- return true;
- }
- }
- }
- return false;
- }
- Location GetLocation(string name, Type type)
- {
- ExternalLocationReference reference;
- if (this.symbols.TryGetValue(name, out reference))
- {
- if (reference.Type == type)
- {
- // We're the same reference
- return reference.Location;
- }
- }
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.SymbolResolverDoesNotHaveSymbol(name, type)));
- }
- public LocationReferenceEnvironment AsLocationReferenceEnvironment()
- {
- return new SymbolResolverLocationReferenceEnvironment(this);
- }
- class SymbolResolverLocationReferenceEnvironment : LocationReferenceEnvironment
- {
- SymbolResolver symbolResolver;
- public SymbolResolverLocationReferenceEnvironment(SymbolResolver symbolResolver)
- {
- this.symbolResolver = symbolResolver;
- }
- public override Activity Root
- {
- get
- {
- return null;
- }
- }
- public override bool IsVisible(LocationReference locationReference)
- {
- if (locationReference == null)
- {
- throw FxTrace.Exception.ArgumentNull("locationReference");
- }
- return this.symbolResolver.IsVisible(locationReference);
- }
- public override bool TryGetLocationReference(string name, out LocationReference result)
- {
- if (string.IsNullOrEmpty(name))
- {
- throw FxTrace.Exception.ArgumentNullOrEmpty("name");
- }
- return this.symbolResolver.TryGetLocationReference(name, out result);
- }
- public override IEnumerable<LocationReference> GetLocationReferences()
- {
- List<LocationReference> list = new List<LocationReference>();
- foreach (ExternalLocationReference item in this.symbolResolver.symbols.Values)
- {
- list.Add(item);
- }
- return list;
- }
- }
- class ExternalLocationReference : LocationReference
- {
- ExternalLocation location;
- string name;
- Type type;
- public ExternalLocationReference(string name, Type type, object value)
- {
- this.name = name;
- this.type = type;
- this.location = new ExternalLocation(this.type, value);
- }
- public object Value
- {
- get
- {
- return this.location.Value;
- }
- }
- public Location Location
- {
- get
- {
- return this.location;
- }
- }
- protected override string NameCore
- {
- get
- {
- return this.name;
- }
- }
- protected override Type TypeCore
- {
- get
- {
- return this.type;
- }
- }
- public override Location GetLocation(ActivityContext context)
- {
- SymbolResolver resolver = context.GetExtension<SymbolResolver>();
- if (resolver == null)
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CanNotFindSymbolResolverInWorkflowInstanceExtensions));
- }
- return resolver.GetLocation(this.Name, this.Type);
- }
- class ExternalLocation : Location
- {
- Type type;
- object value;
- public ExternalLocation(Type type, object value)
- {
- this.type = type;
- this.value = value;
- }
- public override Type LocationType
- {
- get
- {
- return this.type;
- }
- }
- protected override object ValueCore
- {
- get
- {
- return this.value;
- }
- set
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ExternalLocationsGetOnly));
- }
- }
- }
- }
- }
- }