This feature has apparently existed for years, but I found out only now. CLR has an equivalent of HTTP redirect for types, it is called You can move a class from one assembly to another, it is called TypeForwardedTo attribute.
If type T has been moved from assembly A to assembly B, new version of assembly A may reference assembly B, and include [assembly:TypeForwardedTo(typeof(Some.Namespace.T)]
attribute. Full type name, including namespace, must be the same in A and B. Whenever someone requests Some.Namepsace.T, A
, CLR silently gives them Some.Namespace.T, B
instead. It is OK for A and B to be strongly named and signed by different keys.
An example is on GitHub: https://github.com/ikriv-samples/TypeForwardingTest.
Apparently, this is extensively used in .NetStandard as explained in this video. At compile time class libraries targeting .NetStandard reference dotnetstandard.dll
that contains empty implementations of classes, and at runtime they are given another version of dotnetstandard.dll
that type-forwards those impelmentations to the real ones on the current platform, e.g. System.String, dotnetstandard
becomes System.String, mscorlib
on regular .NET and System.String, System.Runtime
on .NET Core.