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