You're not accessing any members of SampleViewModel
- it's not enough to just reference the type itself.
Mapper.Map
only accesses its own internal "dictionary" of mappings - before it could ever get to a point where it deals with a SampleViewModel
, it fails. The static constructor never runs, so it cannot add "itself" into the Mapper
.
Now, if this didn't involve reflection, you would be right that the static constructor would be called - simply because it would happen during the compilation of the method containing the access, e.g.:
var obj = Mapper.Map<SampleViewModel>(s);
Console.WriteLine(obj.SomeField);
In this case, since the method is referencing a field on SampleViewModel
, the static constructor for SampleViewModel
will be invoked during JIT compilation of the containing method, and as such, the Mapper.Map<SampleViewModel>(s)
line will execute correctly, since the mapping is now present. Needless to say this is not the proper solution to your problem. It would just make the code absolutely horrible to maintain :)
DISCLAIMER: Even though this might fix the problem right now, it depends on a non-contractual behaviour in the current implementation of MS.NET on Windows. The contract specifies that the type initializer is invoked before any access to a member of the type, but that still means that a valid implementation of CIL might only call the type initializer after Mapper.Map
, as long as it happens before obj.SomeField
- and even then, it might be that obj.SomeField
gets optimized away if the compiler can ensure it is safe to do so. The only real way to enforce the call of the type initializer is to call RuntimeHelpers.RunClassConstructor
, but by that point, you could just as well add a static Init
method or something.
The real problem is that you shouldn't really initialize stuff like this in a static constructor in the first place. Mappings should be set in some kind of deterministic initialization process, say, an explicitly invoked InitMappings
method. Otherwise you're opening yourself to a huge can of Heisenbugs, not to mention subtle changes in the CLR breaking your whole application for no apparent reason.
Static constructors just aren't meant for "registration", just the initialization of the type itself - anything else is an abuse, and will cause you (or the .NET compatibility team) trouble.