哪些步骤,以域中性组件?组件、步骤

2023-09-03 10:33:06 作者:◆◇″猜不到结局的故事

...并可以将这些步骤也适用于第三方组件(这​​可能已经是强名称)?

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

在上下文我的问题不应该是重要的,但我会反正分享:我在考虑做一个记录器(或登录包装),其总是知道什么是日志源为目标,不论大会使用它都在一个AppDomain中,或在多个应用程序域US $ p $垫。我认为实现这一目标的一种方式,是有一个静态的LOGSOURCE属性域中立组装。如果静态属性是在一个域中性总成设置,我想所有的应用程序域会看到它。

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.

推荐答案

组件未标记为域中性在任何特定的方式。你不必给他们一些特定的属性,使其域无关。任何组件可以由CLR或者到共享域或触发装配载荷根据 CLR实例的配置正在加载组件域被加载。

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.

如何在CLR实例决定加载程序集是由政策决定的。有几种方法可以明确地设置此策略:

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

设置LoaderOptimizationAttribute在你的可执行文件的入口点(通常是主)。 CLR的加载程序将启动可执行文件时使用指定的策略。 设置的AppDomainSetup.LoaderOptimization物业时创建的管理code一个新的应用领域。 CorBindToRuntimeEx的 - 开始从非托管code CLR的时候,这个功能可以让你指定启动的标志。 set LoaderOptimizationAttribute on your executable's entry point (usually Main). The CLR loader will apply the specified policy when starting the executable. set the AppDomainSetup.LoaderOptimization property when creating a new app domain from managed code. CorBindToRuntimeEx - when starting the CLR from unmanaged code, this function allows you to specify start-up flags, some of which control the loader optimization.

加载域的中性的组件将被装入到共享域。该应用程序的域名为EE共享配件库,在CLRv4。这不是一个真正的应用程序域,因为它没有数据,不能运行任何code。组件加载到将分享其$​​ C $ C所有其他正在运行的应用程序域之间。字节code的组装将是JIT编译一次。在装配所有的可变数据,但是,将正在运行的域之间复制。 静态字段不是应用程序域之间共享。每应用程序域静态字段将被复制和不同的应用程序域将读写指的是同一个静态字段时,不同的地方在内存中。

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.

旁白:还有另外一种静态字段 - RVA静,即在当前进程中的所有应用程序域之间共享。没有办法来声明在C#这样的领域,但它可以在C / CLI来完成。的

有一个折衷使用域中性组件。 访问静态字段比较慢。因为他们是JIT,泰德只有一次,但可以访问每个应用程序域静态字段的多个实例,任何访问静态字段经过额外的间接。当一个组件被直接加载到正在运行的域,静态字段的地址,可以直接嵌入到JIT-特德code。但是,当编译成共享组件code试图访问一个静态字段,它必须首先加载当前域的上下文,然后在那里找到静态字段的地址此域。

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.

如果您加载运行基本上是相同的code多个域,你会想分享尽可能多的组件,除非它显著伤害访问静态字段的性能。一个例子是,决定在为了隔离的单独的应用程序域运行它自己的code部分中的应用。 如果您加载多个领域与不同的code,你想分享只有那些有可能普遍使用的所有不同的组件装配。这些通常是在.NET Framework自身的组件和从GAC加载的所有组件。运行ASP.NET应用程序时,IIS以这种方式工作在默认情况下。 如果你曾经只使用一个应用程序域,你不应该分享什么。常规GUI应用程序是这样的。

注:mscorlib中总是被加载到共享域的

来源和进一步阅读:

应用程序域和组件 域名中性大会 基本.NET,第1卷,Addison Wesley出版的;第8章应用程序域和code管理 Application Domains and Assemblies Domain Neutral Assemblies Essential .NET, Volume 1, Addison Wesley; chapter 8 "AppDomains and Code Management"