What are the steps for making domain-neutral assemblies?
Asked Answered
C

3

6

...and can those steps also be applied to a 3rd party assembly (that might already be strong-named)?

The context for my question should not be important, but I'll share anyway: I'm thinking of making a logger (or log-wrapper) that always knows what "log source" to target, regardless of whether the assemblies using it are in one appdomain, or spread across several appdomains. I think one way to achieve that, is to have a domain-neutral assembly with a static "LogSource" property. If that static property is set in a domain-neutral assembly, I think all appdomains will see it.

Cloak answered 17/6, 2010 at 0:24 Comment(0)
C
19

Assemblies aren't marked as domain-neutral in any specific way. You don't have to give them some specific attribute to make them domain-neutral. Any assembly can be loaded by the CLR either into the shared domain or the domain that triggered the assembly load depending on the configuration of the CLR instance that is loading the assembly.

How the CLR instance decides to load an assembly is dictated by policy. There are several ways to explicitly set this policy:

An assembly loaded as domain-neutral will be loaded into the shared domain. The app domain name is "EE Shared Assembly Repository" in CLRv4. That's not a real app domain, because it has no data and can't run any code. Assemblies loaded into it will share its code among all other running app domains. The byte code in the assembly will be JIT-compiled only once. All mutable data in the assembly, however, will be duplicated among the running domains. Static fields are not shared between app domains. Per-app domain static fields will be duplicated and different app domains will read and write in different places in the memory when referring to the same static field.

Aside: there is another kind of static fields - RVA statics, that are shared among all app domains in the current process. There is no way to declare such a field in C#, but it can be done in C++/CLI.

There is a trade-off in using domain-neutral assemblies. Access to static fields is slower. Since they're JIT-ted only once, but may access multiple instances of a per-app domain static field, any access to a static field goes through an additional indirection. When an assembly is loaded straight into the running domain, the address of the static field can be directly embedded into the JIT-ted code. However, when code compiled into the shared assembly tries to access a static field, it must first load the current domain's context and then find in it the static field address for this domain.

The decision whether to load an assembly into the shared domain or into the running domain depends on your use case, more specifically how many app domains you'd create and what sort of core you'd load into it.

  • If you load multiple domains that run essentially the same code, you'd want to share assemblies as much as possible, unless it's significantly hurting the performance of accessing static fields. An example is an application that decides to run portions of its own code in a separate app domain for the sake of isolation.
  • If you load multiple domains with different code, you'd want to share only assemblies that are likely commonly used by all the different assemblies. These would usually be the .NET Framework's own assemblies and all assemblies loaded from GAC. IIS works this way by default when running ASP.NET apps.
  • If you ever use only one app domain, you shouldn't share anything. A regular GUI application will be like that.

Note: mscorlib is always loaded into the shared domain.

Sources and further reading:

Cella answered 10/1, 2013 at 14:15 Comment(2)
Is there a way to mark a class library assembly as domain neutral. The LoaderOptimizationAttribute can only be set on a Main method. Class libraries don't have that.Jovial
Very thorough answer! I would upvote you twice if I could. @AbhijeetPatel That's a good question. I'm having the same issue, where I can't specify this attribute on a class library.Hirsute
I
3

Domain-neutral assemblies share only code across appdomains. However, data is still per-appdomain. Thus, there will be one copy of your static LogSource property for each domain.

Inborn answered 17/6, 2010 at 0:44 Comment(6)
But how do you create a domain-neutral assemblies? And can a 3rd party (possibly strong-named) assembly be converted too?Cloak
You don't do anything specific at assembly build time. The CLR decides at load time if the assembly can be loaded as domain-neutral based on the host and the appdomain policies.Inborn
@Franci: I'm seeing a different story (drdobbs.com/…). It appears I can only make a main program domain-neutral, and it must be decorated with the LoaderOptimizationAttribute. Have I answered my own question, or does .net 3.5 or 4.0 change the story?Cloak
I am not sure how that is a different story. The attribute is just a hint to the loader what policies to set on the appdomain when it is created. However, you can set the same policy when you are explicitly creating new domain through the CLR host interfaces. Meanwhile, once the policy on the appdomain is set, it affects loading other assemblies in the appdomain, not only the assembly containing the Main method.Inborn
I think the link I gave in my comment above is 75% the answer I was looking for. But if you will be more specific about the "CLR host interface", I will mark it as the answer. For example, what are the signatures you have in mind?Cloak
There is an unmanaged interface that can be used by C++ applications to load the CLR and host it in their process and create managed appdomains. In fact, it's the same process that is used by the unmanaged loader stub that the OS executes when it loads a managed executable. More info: msdn.microsoft.com/en-us/magazine/cc301479.aspxInborn
D
0

Actually there is one tricky, undocumented, way to share data across domains, but it can cause runtime errors and whole application crash. Author don't recommend using it in real projects, so you can use MarshalByRef objects instead, to share log consumer. But you can share it using that tricks too.

http://geekswithblogs.net/akraus1/archive/2012/07/25/150301.aspx

Disjunct answered 23/7, 2014 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.