using System; using System.Linq; using System.Collections.Generic; using System.Collections.Concurrent; using System.Reflection; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; var registry = new Dictionary>(StringComparer.Ordinal) { ["rune"] = () => new RuneMessage() }; IMessage direct = registry["rune"](); IMessage reflected = Create(typeof(RuneMessage)); if (reflected.Text != direct.Text) throw new InvalidOperationException("Activation disagreed"); Console.WriteLine($"message:{direct.Text}"); Console.WriteLine($"missing:{registry.TryGetValue("other", out _)}"); static IMessage Create([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type) => (IMessage)Activator.CreateInstance(type)!; public interface IMessage { string Text { get; } } public sealed class RuneMessage : IMessage { public RuneMessage() { } public string Text => "rune"; }