Forum Discussion

RobbSalzmann's avatar
RobbSalzmann
Valued Contributor II
5 months ago

Re: Extract args properties

Not sure what you are asking for, in the title you say properties, then in the body of your post you want functions(assuming methods).  The examples below provide either.

Here is an example that uses the Reflection API to parse properties and their values, GetAllPropertyNamesAndValues and parse the names of the public Methods, GetAllMethodNamesAsList on the args.CubeView object passed into Main on a CubeViewExtender:

Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Globalization
Imports System.IO
Imports System.Reflection
Imports System.Linq
Imports Microsoft.VisualBasic
Imports OneStream.Finance.Database
Imports OneStream.Finance.Engine
Imports OneStream.Shared.Common
Imports OneStream.Shared.Database
Imports OneStream.Shared.Engine
Imports OneStream.Shared.Wcf
Imports OneStream.Stage.Database
Imports OneStream.Stage.Engine
Imports Newtonsoft.Json

Namespace OneStream.BusinessRule.CubeViewExtender.IntrospectionReflector
	Public Class MainClass
		Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As CVExtenderArgs) As Object
			Try
				'Reflect the methods of args.CubeView
				Dim ArgsCubeViewFunctions As List(Of String) = GetAllMethodNamesAsList(args.CubeView)
				BRApi.ErrorLog.LogMessage(si, JsonConvert.SerializeObject(ArgsCubeViewFunctions, Formatting.Indented))
				
				Dim ArgsCubeViewProperties As Dictionary(Of String, Object) = GetAllPropertyNamesAndValues(args.CubeView)
				BRApi.ErrorLog.LogMessage(si, JsonConvert.SerializeObject(ArgsCubeViewProperties, Formatting.Indented))

				Return Nothing
			Catch ex As Exception
				Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
			End Try
		End Function
		
        ''' <summary>
        ''' Return all instance method names defined on the provided cubeView object.
        ''' Filters out compiler "special name" methods (for example, property getters and setters).
        ''' </summary>
        ''' <param name="cubeView">The args.CubeView object to inspect.</param>
        ''' <param name="includeNonPublic">Set True to include Friend/Private instance methods.</param>
        Public Function GetAllMethodNamesAsList(cubeView As Object,
                                                       Optional includeNonPublic As Boolean = False) As List(Of String)
            If cubeView Is Nothing Then
                Throw New ArgumentNullException(NameOf(cubeView), "cubeView cannot be null.")
            End If

            Dim flags As BindingFlags = BindingFlags.Instance Or BindingFlags.Public
            If includeNonPublic Then
                flags = flags Or BindingFlags.NonPublic
            End If

            Dim typeInfo As Type = cubeView.GetType()

            Dim methodNames As List(Of String) =
                typeInfo.
                    GetMethods(flags).
                    Where(Function(m) Not m.IsSpecialName).               ' Exclude get_Foo/set_Foo, add_Event, op_*, etc.
                    Select(Function(m) m.Name).
                    Distinct(StringComparer.Ordinal).
                    OrderBy(Function(n) n, StringComparer.Ordinal).
                    ToList()

            Return methodNames
        End Function
		
		 ''' <summary>
        ''' Return all readable, non-indexed instance property names and their current values
        ''' for the provided cubeView object. If a property getter throws, the dictionary value
        ''' contains a descriptive error string rather than raising an exception.
        ''' </summary>
        ''' <param name="cubeView">The args.CubeView object to inspect.</param>
        ''' <param name="includeNonPublic">Set True to include Friend/Private instance properties.</param>
        Public Function GetAllPropertyNamesAndValues(cubeView As Object,
                                                            Optional includeNonPublic As Boolean = False) As Dictionary(Of String, Object)
            If cubeView Is Nothing Then
                Throw New ArgumentNullException(NameOf(cubeView), "cubeView cannot be null.")
            End If

            Dim flags As BindingFlags = BindingFlags.Instance Or BindingFlags.Public
            If includeNonPublic Then
                flags = flags Or BindingFlags.NonPublic
            End If

            Dim typeInfo As Type = cubeView.GetType()
            Dim result As New Dictionary(Of String, Object)(StringComparer.Ordinal)

            For Each propertyInfo As PropertyInfo In typeInfo.GetProperties(flags)
                ' Skip write-only or indexer properties (those that require parameters).
                If Not propertyInfo.CanRead Then
                    Continue For
                End If
                If propertyInfo.GetIndexParameters().Length > 0 Then
                    Continue For
                End If

                Dim value As Object = Nothing
                Try
                    value = propertyInfo.GetValue(cubeView, Nothing)
                Catch ex As TargetInvocationException
                    Dim root As Exception = If(ex.InnerException, ex)
                    value = String.Format($"<Error retrieving value: {root.GetType().Name}: {root.Message}>")
                Catch ex As Exception
                    value = String.Format($"<Error retrieving value: {ex.GetType().Name}: {ex.Message}>")
                End Try

                result(propertyInfo.Name) = value
            Next

            ' Sort into a new dictionary for deterministic ordering when enumerated.
            Dim ordered As New Dictionary(Of String, Object)(
                result.OrderBy(Function(kv) kv.Key, StringComparer.Ordinal).
                       ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value),
                StringComparer.Ordinal)

            Return ordered
        End Function
	End Class
End Namespace

 

No RepliesBe the first to reply