Marc Gravell wrote:
That is more or less where I got to... I'll avoid the reflection,
though - seems a bit scrappy : but thanks all the same.
The why is complex, and relates to registering a few interfaces with a
lookup (dictionary mapping interfaces to instances implementing that
interface), for use e.g. by some generic lazy-loading, where the "thing
doing the loading" (i.e. an uninitialised collection of orders) knows
how to get its data in terms of interfaces (providers / adapters for
want of a better term), but doesn't know who (which specific class)
will be providing the data. Until I applied the "new()" bit, in a few
test cases no class was registering itself as the provider in time for
the lazy lookup, so it was failing (gracefully).
With the fix, things are correctly saying "hey, I exist and can do
<x>"...
Perhaps I'm being too traditional with this approach, but I would solve
this problem by taking it out "from under the covers" as it were. If
the problem is to register a bunch of classes against some interfaces
and thus to achieve some sort of dynamic loading scenario ("I loaded
this assembly and now I can do these things....") then perhaps this is
something to do explicitly in code, rather than trying to make it
happen "magically" under the covers.
In brief, perhaps you've outsmarted yourself. I do it all the time. :-)
Let's say that you want to load an assembly and then register all of
the classes in it with your dictionary, so that you know which
interfaces have implementations in that assembly, and which classes
correspond to which interfaces. I would put a sealed class called
"RegisterCapabilities" (or something equally illuminating) into the
assembly, and give it one static method, something like "Register". The
Register method would register all of the classes in the assembly with
the dictionary, either by doing so explicitly (my personal choice) or
by calling each class and asking it to register itself.
Then, when your application loads an assembly, it should call
RegisterCapabilities.Register() as its first act. If the assembly
doesn't contain that class and static method, then it's malformed and
can't be used.
If you're not dynamically loading the assembly, then your main program
can do this as the first thing it does, since the correct routine to
call is already known.
Since the registration is now explicit in code, you can easily ensure
that it's happening at the right place without any jiggery-pokery in
static initializers. I think that this solution would also be easier to
maintain: the code is explicit and it's easy to see what it does (and
easy to debug if it fails).
As I said: perhaps that solution is too clunky. I tend to prefer things
out where I can see them... every time I've experimented with clever,
under-the-covers, "magic" solutions to problems, those solutions have
come back to bite me.... :-)