question

MaciejKrzemiski-7893 avatar image
0 Votes"
MaciejKrzemiski-7893 asked MaciejKrzemiski-7893 edited

CLR, when does it actually loads referenced assembly

Hi all, my first question here so please be forgiving.

I'll try not to get in too much of business logic here. What my problem is, in general, is that depending of what properties given class has on itself, then regular typeof(className) causes some third party dll to be loaded, depending on whether the property is a struct or a class. My setup is as follows:
- Main app X (I own the codes)
- Assembly Integration (I also own the codes)
- Assembly External (3rd party, I don't have access to it) exposing two example types ClassType (which is obviously a class) and a StructType (accordingly is a struct)

Now my Integration assembly has a type DeviceV which has two properties, one of type ClassType, and second one of type StructType from External assembly. During compile time External assembly is of course available, but after deployment it's rarely there, depending on some business rules, doesn't matter.
Now, Integration has some logic that needs to check if object is a specific type, for e.g. deviceInterface.GetType() == typeof(DeviceV). And now the riddle occurs. It throws FileNotFoundException, obviously External assembly was not found as expected. But when I remove StructType from DeviceV, everything works like a charm.
DeviceV is never created, there's no code invoked here which I don't know of. You can very simply reproduce this locally on any machine with almost blank projects and I did it myself.

The question is WHY? I've checked Metadata of Integration assembly and it contains information about both ClassType and StructType. Moreover StructType is basically included in Integration's MetaData, whole.
Why CLR is trying to load the assembly whenever underlying type in typeof() is using struct from other assembly but not for a class? Why is it trying to load anything at all? At that point I'd assume that it has all the information it needs to perform the operation.

I don't need any solutions to this problem, it's not a blocker, workaround is simple. I simply cannot stop thinking about it and can't find the answer neither on the web or in the literature, WHY IS CLR DOING THIS? I am sure that there is a reason for this and I want to know it.

Thanks in advance!

[EDIT]
Well I think I've found the answer, if anyone cares. First of all, structure is not compiled into metadata completely, only the parts that were used and a compressed signature of the field type. Secondly, jitter sources (clr repo) claim that all value types are loaded before method is invoked, thus explaining different behavior when structure is involved.

dotnet-csharpdotnet-runtime
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

No document is going to cover all the details, so your primary hope is the CLR source code https://github.com/dotnet/runtime

0 Votes 0 ·

There is a reason "late binding" (also known as "dynamic reference") exists and it does exactly what you want.

If you add assemblies by "Add reference", they'll always be loaded as soon as your application starts.


0 Votes 0 ·

Maybe it is a limitation. We can be also surprised that the dependent assembly is not always loaded (needed) when you call typeof(DeviceV). Perhaps the engine includes an optimisation, which is not available in case of structures and maybe there is no reason to not implement such optimisation.

0 Votes 0 ·

0 Answers