Shared static constructors from C# EXE

Thalamus via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Feb 25 06:01:30 PST 2016


Hi everyone,

I looked in the forums and Google in general but I didn't find a 
similar question, and I'm stumped. I have a scenario where a set 
of classes must be registered with a class mapper and then 
instantiated via a factory. The classes themselves are agnostic 
of one another, and all interaction with these classes after 
instantiation is via interfaces. I've succeeded in having the 
classes register themselves at runtime by using shared static 
constructors, which is really seamless! This works just fine when 
the EXE is written in D, but only a subset of shared static 
constructors get called when the EXE is written in C#.

A few more details:

ClassMapper class includes a shared static constructor that 
initializes a class map associative array, and it exposes a 
public Map() function an Instantiate(TypeInfo_Class classType, 
etc.) function.
Class A and Class B both have shared static constructors that 
call Map() to register themselves.

The above is built into a D EXE, and ClassMapper.map is fully 
populated before main() starts.

-OR-

The above is built into a D DLL with a CreateClassB() function 
exposed via .def, etc. A C# EXE invokes CreateClassB() via 
p/invoke.

The call works just fine, and ClassB and anything class B calls, 
recursively, are all registered with ClassMapper.map just fine, 
because their shared static constructors are invoked. But, Class 
A is not in the map because its shared static constructor is 
never called.

I don't control the EXE itself and the code I write to interface 
with it must be either C# or JavaScript, but this repros with a 
test C# driver EXE as well. The interfacing C# code can only be 
aware of the exposed D DLL functions defined in .def and 
shouldn't be aware directly of Class A, B, or ClassMapper, the 
factory specifically, etc..

Has anyone seen this before, or have an idea for a workaround? 
The best workaround I've come up with so far is to use a registry 
config file instead of calls to Map() so the ClassMapper can 
populate itself. It's not a very elegant solution, but it was the 
best I was able to come up with for C++ too. (In C# I've used 
class attributes, which I had thought was elegant. D's shared 
static constructors are even more so, though.)

thanks much!
Thalamus


More information about the Digitalmars-d-learn mailing list