/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ namespace Microsoft.Rest.ClientRuntime { using System; /// /// PowerShell-specific data on top of the llc# EventData /// /// /// In PowerShell, we add on the EventDataConverter to support sending events between modules. /// Obviously, this code would need to be duplcated on both modules. /// This is preferable to sharing a common library, as versioning makes that problematic. /// [System.ComponentModel.TypeConverter(typeof(EventDataConverter))] public partial class EventData : EventArgs { } /// /// A PowerShell PSTypeConverter to adapt an EventData object that has been passed. /// Usually used between modules. /// public class EventDataConverter : System.Management.Automation.PSTypeConverter { public override bool CanConvertTo(object sourceValue, Type destinationType) => false; public override object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) => null; public override bool CanConvertFrom(dynamic sourceValue, Type destinationType) => destinationType == typeof(EventData) && CanConvertFrom(sourceValue); public override object ConvertFrom(dynamic sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) => ConvertFrom(sourceValue); /// /// Verifies that a given object has the required members to convert it to the target type (EventData) /// /// Uses a dynamic type so that it is able to use the simplest code without excessive checking. /// /// The instance to verify /// True, if the object has all the required parameters. public static bool CanConvertFrom(dynamic sourceValue) { try { // check if this has *required* parameters... sourceValue?.Id?.GetType(); sourceValue?.Message?.GetType(); sourceValue?.Cancel?.GetType(); // remaining parameters are not *required*, // and if they have values, it will copy them at conversion time. } catch { // if anything throws an exception (because it's null, or doesn't have that member) return false; } return true; } /// /// Returns result of the delegate as the expected type, or default(T) /// /// This isolates any exceptions from the consumer. /// /// A delegate that returns a value /// The desired output type /// The value from the function if the type is correct private static T To(Func srcValue) { try { return srcValue(); } catch { return default(T); } } /// /// Converts an incoming object to the expected type by treating the incoming object as a dynamic, and coping the expected values. /// /// the incoming object /// EventData public static EventData ConvertFrom(dynamic sourceValue) { return new EventData { Id = To(() => sourceValue.Id), Message = To(() => sourceValue.Message), Parameter = To(() => sourceValue.Parameter), Value = To(() => sourceValue.Value), RequestMessage = To(() => sourceValue.RequestMessage), ResponseMessage = To(() => sourceValue.ResponseMessage), Cancel = To(() => sourceValue.Cancel) }; } } }