Does anyone know if it is possible to define the equivalent of a "java custom class loader" in .NET?
To give a small background:
I am developing a new programming language that focuses on the CLR, called Freedom. One of the features of the language is its ability to define "type constructors", which are methods that are executed by the compiler at compile time and generate types as output. This is a kind of generalization of generics (it has normal generics) and allow such a code (in the syntax "Freedom"):
var t as tuple<i as int, j as int, k as int>; ti = 2; tj = 4; tk = 5;
Where the "tuple" is defined as follows:
public type tuple(params variables as VariableDeclaration[]) as TypeDeclaration {
In this particular example, the tuple type constructor provides something similar to anonymous types in VB and C #.
However, unlike anonymous types, "tuples" have names and can be used inside public method signatures.
This means that I need a way for a type that ultimately ends up being emitted by the compiler for sharing in multiple assemblies. For example, I want
tuple<x as int> defined in assembly A to ultimately be the same type as tuple<x as int> defined in assembly B.
The problem with this, of course, is that assembly A and assembly B are assembled at different times, which means that they will both issue their own incompatible versions of the tuple type.
I was looking to use some kind of type erase for this, so I would have a shared library with a bunch of types like this (this is the "Freedom" syntax):
class tuple<T> { public Field1 as T; } class tuple<T, R> { public Field2 as T; public Field2 as R; }
and then simply redirect access from fields i, j and k tuple to Field1 , Field2 and Field3 .
However, this is not a very effective option. This would mean that at compile time, tuple<x as int> and tuple<y as int> will ultimately be different types, while at run time they will be treated as the same type. This can cause a lot of problems for things like identifying equality and type. It is too impenetrable for abstraction for my tastes.
Other possible options would be to use “state bag objects”. However, using a state bag can defeat the whole purpose of supporting "type constructors" in a language. The idea is to enable "custom language extensions" to generate new types at compile time, with which the compiler can execute a static type with.
In Java, this can be done using custom class loaders. Basically, code that uses tuple types can be issued without actually defining the type on disk. Then, a custom “class loader” can be defined that will dynamically generate a tuple type at runtime. This will allow you to check the static type inside the compiler and unify the types of tuples across compilation boundaries.
Unfortunately, however, the CLR does not support loading a custom class. All loading in the CLR is done at the assembly level. It would be possible to define a separate assembly for each "built type", but this would very quickly lead to performance problems (having many assemblies with one type in them would use too many resources).
So I want to know:
Is it possible to simulate something like Java Class Loaders in .NET, where I can fix the link to a non-existent type and then dynamically generate a link to this type at runtime before the code that it needs to use is run
Note:
* I really already know the answer to the question that I provide as an answer below. However, it took me about 3 days of research and quite a bit of hacking IL to come up with a solution. I thought it would be nice to document it here if someone else ran into the same problem. *