/// <summary> /// Creates the reference URL generator cache. /// </summary> private void InitReferenceUrlGeneratorCache() { // Get all the types in this assembly IEnumerable <Type> allTypes = Assembly.GetExecutingAssembly().GetExportedTypes(); // Get all the cmdlets that return resources (i.e. not "$ref", function or action cmdlets) IEnumerable <Type> referenceableCmdletTypes = allTypes // Select only the types that represent "$ref" cmdlets .Where(type => type.IsClass && !type.IsAbstract // Is a "GET" cmdlet that returns resources that can be referenced && typeof(GetCmdlet).IsAssignableFrom(type) && type.GetCustomAttribute <ResourceReferenceAttribute>() != null); // For each "GET" cmdlet, create a mapping to a ReferencePathGenerator foreach (Type cmdletType in referenceableCmdletTypes) { // Construct an instance of the cmdlet object constructedCmdlet = cmdletType .GetConstructor(Array.Empty <Type>())? .Invoke(Array.Empty <object>()); // Make sure we were able to construct an instance of the cmdlet if (constructedCmdlet is ODataCmdletBase cmdlet) { // Get this cmdlet name's noun string cmdletNoun = cmdlet.GetCmdletNoun(); // Create the URL generator ReferencePathGenerator urlGenerator = new ReferencePathGenerator(cmdlet); // Add the mapping ReferencePathGenerator.AddToCache(cmdletNoun, urlGenerator); } } }
/// <summary> /// Processes a result object. /// </summary> /// <param name="obj">The result object to process</param> internal void ProcessResultObject(object obj) { if (obj is PSObject psObj) { // Track the properties to hide ICollection <string> propertiesToHide = new List <string>(); // Add alias for the "id" property if it exists on the result object string objectId = psObj.Properties[ODataConstants.SearchResultProperties.Id]?.Value as string; if (objectId != null) { // Get the name of the alias property string idPropertyName = this.GetResourceIdPropertyName(); if (idPropertyName != null) { // Create the alias psObj.Properties.Add(new PSAliasProperty(idPropertyName, ODataConstants.SearchResultProperties.Id)); // Hide this property propertiesToHide.Add(idPropertyName); } } // ID parameters for parent resources foreach (var entry in this.GetIdParameterNamesAndValues()) { // Create the property string propertyName = entry.Key; string propertyValue = entry.Value; psObj.Properties.Add(new PSNoteProperty(propertyName, propertyValue)); // Hide this property propertiesToHide.Add(propertyName); } // Type cast parameters for parent resources foreach (var entry in this.GetTypeCastParametersAndValues()) { // Add a property to store the type name string propertyName = entry.Key; string propertyValue = entry.Value; psObj.Properties.Add(new PSNoteProperty(propertyName, propertyValue)); // Hide this property propertiesToHide.Add(propertyName); } // Get the type name without the leading "#" string typeName = (psObj.Properties[ODataConstants.SearchResultProperties.ODataType]?.Value as string)?.TrimStart('#'); if (string.IsNullOrEmpty(typeName)) { typeName = this.GetType().GetCustomAttribute <ODataTypeAttribute>(false)?.TypeFullName; } if (typeName != null) { // Add the type name to the list of PowerShell type names for this object psObj.TypeNames.Insert(0, typeName); // Add the type cast property string typeCastPropertyName = this.GetResourceTypePropertyName(); psObj.Properties.Add(new PSNoteProperty(typeCastPropertyName, typeName)); // Hide the type cast property propertiesToHide.Add(typeCastPropertyName); // If this cmdlet retrieves resources that can be referenced, add a property to represent the URL which can be used to retrieve this object if (ReferencePathGenerator.TryGetFromCache(this.GetCmdletNoun(), out ReferencePathGenerator pathGenerator)) { // Get the full resource URL string referencePath = pathGenerator.GenerateResourcePath(this, objectId); string referenceUrl = this.BuildUrl(referencePath); // Add this reference URL as a property string referenceUrlPropertyName = ODataTypeUtils.GetReferenceUrlParameterName(typeName); psObj.Properties.Add(new PSNoteProperty(referenceUrlPropertyName, referenceUrl)); // Hide this property propertiesToHide.Add(referenceUrlPropertyName); } } // Hide the properties we have been tracking psObj.SetDefaultDisplayProperties(prop => !propertiesToHide.Contains(prop.Name)); } }