/// <summary> /// Builds a timestamp schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="StringSchema" />. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not a <see cref="TimestampResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is TimestampResolution timestamp)) { throw new UnsupportedTypeException(resolution.Type); } Schema schema = null; switch (TemporalBehavior) { case TemporalBehavior.Iso8601: schema = new StringSchema(); break; case TemporalBehavior.EpochMilliseconds: schema = new LongSchema { LogicalType = new MillisecondTimestampLogicalType() }; break; case TemporalBehavior.EpochMicroseconds: schema = new LongSchema { LogicalType = new MicrosecondTimestampLogicalType() }; break; default: throw new ArgumentOutOfRangeException(nameof(TemporalBehavior)); } return(cache.GetOrAdd(timestamp.Type, schema)); }
/// <summary> /// Builds an enum schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="EnumSchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not an <see cref="EnumResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is EnumResolution @enum)) { throw new UnsupportedTypeException(resolution.Type); } if (@enum.IsFlagEnum) { return(cache.GetOrAdd(@enum.Type, type => SchemaBuilder.BuildSchema(@enum.UnderlyingType, cache))); } else { var name = @enum.Namespace == null ? @enum.Name.Value : $"{@enum.Namespace.Value}.{@enum.Name.Value}"; var schema = new EnumSchema(name); foreach (var symbol in @enum.Symbols) { schema.Symbols.Add(symbol.Name.Value); } return(cache.GetOrAdd(@enum.Type, schema)); } }
/// <summary> /// Builds an enum schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="EnumSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not an <see cref="EnumResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is EnumResolution @enum)) { throw new ArgumentException("The enum case can only be applied to enum resolutions.", nameof(resolution)); } if (@enum.IsFlagEnum) { var schema = new LongSchema(); cache.Add(@enum.Type, schema); return(schema); } else { var name = @enum.Namespace == null ? @enum.Name.Value : $"{@enum.Namespace.Value}.{@enum.Name.Value}"; var schema = new EnumSchema(name); cache.Add(@enum.Type, schema); foreach (var symbol in @enum.Symbols) { schema.Symbols.Add(symbol.Name.Value); } return(schema); } }
/// <summary> /// Construct content within propertyName dashboard gadget. It is assumed that view consists of propertyName /// constructor that takes viewmodel instance and view model class consists od propertyName cons- /// tructor that takes IEventAggregator, IDBInteractivity and ILoggerFacade instance. /// </summary> /// <param name="gadgetViewClassName">Gadget view Type</param> /// <param name="gadgetViewModelClassName">Gadget View Model Type</param> /// <returns></returns> private object GetDashboardTileContent(string displayName, string gadgetViewClassName, string gadgetViewModelClassName, object viewModelObject = null) { object content = null; try { Assembly assembly = TypeResolution.GetAssembly(gadgetViewClassName); Type viewType = TypeResolution.GetAssemblyType(gadgetViewClassName); Type viewModelType = viewModelObject == null?TypeResolution.GetAssemblyType(gadgetViewModelClassName) : viewModelObject.GetType(); if (viewType.IsClass && viewModelType.IsClass) { Type[] argumentTypes = new Type[] { typeof(DashboardGadgetParam) }; object[] argumentValues = new object[] { GetDashboardGadgetParam(displayName) }; if (viewModelObject == null) { viewModelObject = TypeResolution.GetNewTypeObject(viewModelType, argumentTypes, argumentValues); } content = TypeResolution.GetNewTypeObject(viewType, new Type[] { viewModelType }, new object[] { viewModelObject }); ViewBaseUserControl control = (ViewBaseUserControl)(content); if (control != null) { control.IsActive = true; } } } catch (Exception ex) { logger.Log("User : "******"\nMessage: " + ex.Message + "\nStackTrace: " + ex.StackTrace, Category.Exception, Priority.Medium); Prompt.ShowDialog("Message: " + ex.Message + "\nStackTrace: " + ex.StackTrace, "Exception", MessageBoxButton.OK); } return(content); }
/// <summary> /// Construct content within propertyName dashboard gadget. It is assumed that view consists of propertyName /// constructor that takes viewmodel instance and view model class consists od propertyName cons- /// tructor that takes DashboardGadgetParam instance. /// </summary> /// <param name="gadgetViewClassName">Gadget view Type</param> /// <param name="gadgetViewModelClassName">Gadget View Model Type</param> /// <returns></returns> public static object GetContent(string gadgetViewClassName , string gadgetViewModelClassName, DashboardGadgetParam param) { if (gadgetViewClassName == null || gadgetViewModelClassName == null || param == null) { throw new ArgumentNullException(); } object content = null; try { Assembly assembly = TypeResolution.GetAssembly(gadgetViewClassName); Type viewType = TypeResolution.GetAssemblyType(gadgetViewClassName); Type viewModelType = TypeResolution.GetAssemblyType(gadgetViewModelClassName); if (viewType.IsClass && viewModelType.IsClass) { Type[] argumentTypes = new Type[] { typeof(DashboardGadgetParam) }; object[] argumentValues = new object[] { param }; object viewModelObject = TypeResolution.GetNewTypeObject(viewModelType, argumentTypes, argumentValues); content = TypeResolution.GetNewTypeObject(viewType, new Type[] { viewModelType }, new object[] { viewModelObject }); } } catch (Exception ex) { param.LoggerFacade.Log("User : "******"\nMessage: " + ex.Message + "\nStackTrace: " + ex.StackTrace, Category.Exception, Priority.Medium); Prompt.ShowDialog("Message: " + ex.Message + "\nStackTrace: " + ex.StackTrace, "Exception", MessageBoxButton.OK); } return(content); }
/// <summary> /// The specified type must have a public parameter-less constructor. /// </summary> internal static bool HasPublicParameterLessConstructor(this TypeResolution type) { var ctors = type.GetConstructors(); if (ctors == null) { return(false); } foreach (var ctor in ctors) { if (!ctor.IsPublic) { continue; } var parameters = ctor.GetParameters(); if (parameters == null || parameters.Count == 1) { return(true); } } return(false); //var parameters = ctors[0].GetParameters(); //return parameters == null; //return ctors != null && ctors.Count == 1; }
/// <summary> /// Builds a double schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A successful <see cref="DoubleSchema" /> build result if <paramref name="resolution" /> /// is a double-precision <see cref="FloatingPointResolution" />; an unsuccessful /// <see cref="UnsupportedTypeException" /> build result otherwise. /// </returns> public override ISchemaBuildResult BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { var result = new SchemaBuildResult(); if (resolution is FloatingPointResolution @double && @double.Size == 16) { result.Schema = cache.GetOrAdd(@double.Type.GetUnderlyingType(), _ => new DoubleSchema()); }
protected virtual Type GetType(string typeName) { if (typeName == null) { throw new ArgumentNullException("typeName"); } return(TypeResolution.GetType(typeName)); }
/// <summary> /// Builds a long schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="LongSchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not an <see cref="IntegerResolution" /> or specifies a /// size less than or equal to 32 bits. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is IntegerResolution @long) || @long.Size <= 32) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(@long.Type, new LongSchema())); }
/// <summary> /// Builds a boolean schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="BooleanSchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not a <see cref="BooleanResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is BooleanResolution boolean)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(boolean.Type, new BooleanSchema())); }
/// <summary> /// Builds a byte array schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="BytesSchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not a <see cref="ByteArrayResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is ByteArrayResolution bytes)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(bytes.Type, new BytesSchema())); }
/// <summary> /// Builds an array schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// An <see cref="ArraySchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not an <see cref="ArrayResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is ArrayResolution array)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(array.Type, new ArraySchema(SchemaBuilder.BuildSchema(array.ItemType, cache)))); }
/// <summary> /// Builds a URI schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="StringSchema" />. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not a <see cref="UriResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is UriResolution uri)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(uri.Type, new StringSchema())); }
/// <summary> /// Builds a float schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="FloatSchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not an 8-bit <see cref="FloatingPointResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is FloatingPointResolution @float) || @float.Size != 8) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(@float.Type, new FloatSchema())); }
/// <summary> /// Builds a map schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="MapSchema" /> that matches the type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not an <see cref="MapResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is MapResolution map)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(map.Type, new MapSchema(SchemaBuilder.BuildSchema(map.ValueType, cache)))); }
/// <summary> /// Tries to get an type that defined in an probable assembly (a runtime or application assembly). /// </summary> public bool TryGetProbableType(string assemblyName, string typeName, out TypeResolution result) { var asm = AssemblyResolution.GetProbableAssembly(assemblyName); if (asm != null) { return(asm.TryGetType(typeName, out result)); } result = null; return(false); }
/// <summary> /// Builds a decimal schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="BytesSchema" /> with a <see cref="DecimalLogicalType" /> that matches the /// type resolution. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not a <see cref="DecimalResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is DecimalResolution @decimal)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(@decimal.Type, new BytesSchema() { LogicalType = new DecimalLogicalType(@decimal.Precision, @decimal.Scale) })); }
/// <summary> /// Builds a UUID schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="StringSchema" />. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the resolution is not a <see cref="UuidResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { if (!(resolution is UuidResolution uuid)) { throw new UnsupportedTypeException(resolution.Type); } return(cache.GetOrAdd(uuid.Type, new StringSchema() { LogicalType = new UuidLogicalType() })); }
/// <summary> /// Builds a map schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="MapSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not an <see cref="MapResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is MapResolution map)) { throw new ArgumentException("The map case can only be applied to map resolutions.", nameof(resolution)); } var schema = new MapSchema(SchemaBuilder.BuildSchema(map.ValueType, cache)); cache.Add(map.Type, schema); return(schema); }
/// <summary> /// Builds a boolean schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="BooleanSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not a <see cref="BooleanResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is BooleanResolution boolean)) { throw new ArgumentException("The boolean case can only be applied to boolean resolutions.", nameof(resolution)); } var schema = new BooleanSchema(); cache.Add(boolean.Type, schema); return(schema); }
/// <summary> /// Builds a byte array schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="BytesSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not a <see cref="ByteArrayResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is ByteArrayResolution bytes)) { throw new ArgumentException("The byte array case can only be applied to byte array resolutions.", nameof(resolution)); } var schema = new BytesSchema(); cache.Add(bytes.Type, schema); return(schema); }
/// <summary> /// Builds a URI schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="StringSchema" />. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not a <see cref="UriResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is UriResolution uri)) { throw new ArgumentException("The URI case can only be applied to URI resolutions.", nameof(resolution)); } var schema = new StringSchema(); cache.Add(uri.Type, schema); return(schema); }
/// <summary> /// Builds a long schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="LongSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not an <see cref="IntegerResolution" /> or specifies a /// size less than or equal to 32 bits. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is IntegerResolution @long) || @long.Size <= 32) { throw new ArgumentException("The long case can only be applied to integer resolutions larger than 32 bits.", nameof(resolution)); } var schema = new LongSchema(); cache.Add(@long.Type, schema); return(schema); }
/// <summary> /// Builds a float schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="FloatSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not an 8-bit <see cref="FloatingPointResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is FloatingPointResolution @float) || @float.Size != 8) { throw new ArgumentException("The double case can only be applied to 8-bit floating point resolutions.", nameof(resolution)); } var schema = new FloatSchema(); cache.Add(@float.Type, schema); return(schema); }
/// <summary> /// Builds a timestamp schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A <see cref="StringSchema" />. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not a <see cref="TimestampResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is TimestampResolution timestamp)) { throw new ArgumentException("The timestamp case can only be applied to timestamp resolutions.", nameof(resolution)); } var schema = new StringSchema(); cache.Add(timestamp.Type, schema); return(schema); }
/// <summary> /// Builds an array schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// An <see cref="ArraySchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not an <see cref="ArrayResolution" />. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is ArrayResolution array)) { throw new ArgumentException("The array case can only be applied to array resolutions.", nameof(resolution)); } var schema = new ArraySchema(SchemaBuilder.BuildSchema(array.ItemType, cache)); cache.Add(array.Type, schema); return(schema); }
/// <summary> /// Builds an int schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// An <see cref="IntSchema" /> that matches the type resolution. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the resolution is not an <see cref="IntegerResolution" /> or specifies a /// size greater than 32 bits. /// </exception> public override Schema BuildSchema(TypeResolution resolution, IDictionary <Type, Schema> cache) { if (!(resolution is IntegerResolution @int) || @int.Size > 32) { throw new ArgumentException("The int case can only be applied to 32-bit or smaller integer resolutions.", nameof(resolution)); } var schema = new IntSchema(); cache.Add(@int.Type, schema); return(schema); }
/// <summary> /// Handles Dashboard Gadget Save event - records preference to database. /// </summary> /// <param name="param">null</param> public void HandleDashboardGadgetSave(object param) { try { ObservableCollection <tblDashboardPreference> dashboardPreference = new ObservableCollection <tblDashboardPreference>(); if (this.rtvDashboard.Items.Count > 0) { string uniqueKey = SessionManager.SESSION.UserName + "-" + DateTime.Now.ToString(); for (int index = 0; index < rtvDashboard.Items.Count; index++) { tblDashboardPreference entry = new tblDashboardPreference() { UserName = SessionManager.SESSION.UserName, PreferenceGroupID = uniqueKey, GadgetViewClassName = TypeResolution.GetTypeFullName((rtvDashboard.Items[index] as RadTileViewItem).Content), GadgetViewModelClassName = TypeResolution.GetTypeDataContextFullName((rtvDashboard.Items[index] as RadTileViewItem).Content), GadgetName = ((rtvDashboard.Items[index] as RadTileViewItem).Header as Telerik.Windows.Controls.HeaderedContentControl).Content.ToString(), GadgetState = (rtvDashboard.Items[index] as RadTileViewItem).TileState.ToString(), GadgetPosition = (rtvDashboard.Items[index] as RadTileViewItem).Position }; dashboardPreference.Add(entry); } } manageDashboard.SetDashboardPreference(dashboardPreference, SessionManager.SESSION.UserName, (result) => { if (result != null) { if ((bool)result) { Prompt.ShowDialog("User Preference saved"); } else { Prompt.ShowDialog("User Preference save failed"); } } else { Prompt.ShowDialog("User Preference save failed"); } }); } catch (Exception ex) { logger.Log("User : "******"\nMessage: " + ex.Message + "\nStackTrace: " + ex.StackTrace, Category.Exception, Priority.Medium); Prompt.ShowDialog("Message: " + ex.Message + "\nStackTrace: " + ex.StackTrace, "Exception", MessageBoxButton.OK); } }
/// <summary> /// Builds a byte array schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A successful <see cref="BytesSchema" /> build result if <paramref name="resolution" /> /// is a <see cref="ByteArrayResolution" />; an unsuccessful <see cref="UnsupportedTypeException" /> /// build result otherwise. /// </returns> public override ISchemaBuildResult BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { var result = new SchemaBuildResult(); if (resolution is ByteArrayResolution bytes) { result.Schema = cache.GetOrAdd(bytes.Type.GetUnderlyingType(), _ => new BytesSchema()); } else { result.Exceptions.Add(new UnsupportedTypeException(resolution.Type)); } return(result); }
/// <summary> /// Builds an array schema. /// </summary> /// <param name="resolution"> /// A type resolution. /// </param> /// <param name="cache"> /// A schema cache. /// </param> /// <returns> /// A successful <see cref="ArraySchema" /> build result if <paramref name="resolution" /> /// is an <see cref="ArrayResolution" />; an unsuccessful <see cref="UnsupportedTypeException" /> /// build result otherwise. /// </returns> public override ISchemaBuildResult BuildSchema(TypeResolution resolution, ConcurrentDictionary <Type, Schema> cache) { var result = new SchemaBuildResult(); if (resolution is ArrayResolution array) { result.Schema = cache.GetOrAdd(array.Type.GetUnderlyingType(), _ => new ArraySchema(SchemaBuilder.BuildSchema(array.ItemType, cache))); } else { result.Exceptions.Add(new UnsupportedTypeException(resolution.Type)); } return(result); }