Reflection, Attributes and Metadata

23.1 Reflection

Plugin isolation and unloading: AssemblyLoadContext (with isCollectible:=True) on modern .NET.

Imports System.Reflection
Dim t = GetType(Account)
Console.WriteLine($"{t.FullName} in {t.Assembly.GetName().Name}")
For Each p In t.GetProperties(BindingFlags.Public Or BindingFlags.Instance)
    Console.WriteLine($"{p.Name}: {p.PropertyType.Name} (CanWrite={p.CanWrite})")
Next
Dim instance = Activator.CreateInstance(t, "Ana")
Dim deposit = t.GetMethod("Deposit")
deposit.Invoke(instance, New Object() {100D})
Dim balance = t.GetProperty("Balance").GetValue(instance)

' Plugin discovery
Dim pluginTypes = From asm In AppDomain.CurrentDomain.GetAssemblies()
                  From pt In asm.GetTypes()
                  Where GetType(IPlugin).IsAssignableFrom(pt) AndAlso Not pt.IsAbstract AndAlso Not pt.IsInterface
                  Select pt

23.2 Attributes

Assembly attributes: <Assembly: AssemblyVersion("1.0.*")>, <Assembly: InternalsVisibleTo("X")>, <Assembly: CLSCompliant(True)>.

Caller info: <CallerMemberName>, <CallerFilePath>, <CallerLineNumber>, <CallerArgumentExpression> (consumed).

<AttributeUsage(AttributeTargets.Property)>
Public NotInheritable Class DisplayNameAttribute
    Inherits Attribute
    Public ReadOnly Property Text As String
    Public Sub New(text As String)
        Me.Text = text
    End Sub
End Class

Public Class Customer
    <DisplayName("Customer Name"), ComponentModel.DataAnnotations.Required, ComponentModel.DataAnnotations.StringLength(100)>
    Public Property Name As String
End Class

Dim headers = From p In GetType(Customer).GetProperties()
              Let a = p.GetCustomAttribute(Of DisplayNameAttribute)()
              Select If(a?.Text, p.Name)

' Validate with DataAnnotations
Dim ctx As New ComponentModel.DataAnnotations.ValidationContext(customer)
Dim errors As New List(Of ComponentModel.DataAnnotations.ValidationResult)
Dim isValid = ComponentModel.DataAnnotations.Validator.TryValidateObject(customer, ctx, errors, validateAllProperties:=True)