Dynamitey
Dynamitey is a .NET library that wraps the Dynamic Language Runtime to do runtime dispatch: late binding, currying, partial application, expando objects, tuple manipulation, and duck-typed proxies.
Jay Tuley (@jbtule) wrote Dynamitey. This documentation covers Dynamitey.Community, the community continuation of ekonbenefits/dynamitey, which has been dormant since its 3.0.3 release in November 2023.
Important
The package is Dynamitey.Community 4.0.0. The original Dynamitey package on NuGet remains upstream's 3.0.3 and does not contain this code.
Where to start
| If you want to | Read |
|---|---|
| See what 4.0.0 contains, and which runtimes it still supports | About 4.0.0 |
| Call a member you cannot see at compile time | Late binding |
| Use a type from an assembly you have no reference to | Late types |
Move from the original Dynamitey package |
Migrating |
| Build object graphs inline | Builders and expandos |
| Curry or partially apply a function | Currying |
| Create or manipulate tuples at runtime | Tuples |
| Await a method whose return type you cannot see | Async |
| Make repeated dynamic calls faster | Caching |
| Look up a specific type or member | API reference |
The shortest example
using Dynamitey;
var target = "a,b,c";
var result = Dynamic.InvokeMember(target, "Split", new object[] { ',' });
That resolves Split at runtime against whatever target actually is. The compiler is not asked to know, which is the point: it works against internal types, types from assemblies you have no reference to, and shapes decided at runtime.
What this library is for
The DLR gives C# the dynamic keyword, and dynamic alone covers most everyday cases. Dynamitey exists for the cases it does not:
- Accessibility.
dynamicresolves members in your assembly's accessibility context, so it cannot reach a private or internal member, and cannot hand you a value whose type you cannot see. Dynamitey can. - Names decided at runtime.
target.Foorequires writingFoo.Dynamic.InvokeMember(target, name, args)does not. - Reuse. A
dynamiccall site is compiler-generated and tied to one location.CacheableInvocationmakes the cached binder an object you hold and reuse across call sites. - Function manipulation. Currying, partial application, and delegate conversion have no
dynamicequivalent at all.
Supported frameworks
netstandard2.0 and net10.0. The netstandard2.0 target is kept deliberately — it is the only target reaching both .NET Framework 4.6.1–4.8.1 and modern .NET from a single assembly.
A word on trimming and AOT
This library is DLR-based and will never be trim-safe or NativeAOT-safe. Rather than fail at runtime, dynamic-dispatch entry points carry [RequiresUnreferencedCode] and [RequiresDynamicCode], so a trimmed or AOT-compiled project gets build-time warnings at the exact call sites that will not survive.