gpt4 book ai didi

c# - 如何获取父 AppDomain?

转载 作者:行者123 更新时间:2023-11-30 15:06:55 27 4
gpt4 key购买 nike

我需要在 C# 中做这样的事情(伪):

static var ns = new Non_Serializable_Nor_Marshal()

var app = new AppDomain();
app.execute(foo)

void foo()
{
var host = AppDomain.Current.Parent; //e.g. the original one
host.execute(bar)
}

void bar()
{
ns.Something();
}

IOW 我在一个应用程序域中有一个不可序列化或编码的对象。我想创建第二个域并执行 foo()。在第二个域中,我想在原始域上执行 bar() 。

如何将原始域传递给子域?

最佳答案

如果您不想使用互操作,您也可以使用 AppDomainManager 使用一些小技巧。您基本上可以自动将“主”域自动“连接”到任何域 - 尽管我这样做的方式意味着您丢弃了真正的主域。

这是完成所有魔法的类:

/// <summary>
/// Represents a <see cref="AppDomainManager"/> that is
/// aware of the primary application AppDomain.
/// </summary>
public class PrimaryAppDomainManager : AppDomainManager
{
private static AppDomain _primaryDomain;

/// <summary>
/// Gets the primary domain.
/// </summary>
/// <value>The primary domain.</value>
public static AppDomain PrimaryDomain
{
get
{
return _primaryDomain;
}
}

/// <summary>
/// Sets the primary domain.
/// </summary>
/// <param name="primaryDomain">The primary domain.</param>
private void SetPrimaryDomain(AppDomain primaryDomain)
{
_primaryDomain = primaryDomain;
}

/// <summary>
/// Sets the primary domain to self.
/// </summary>
private void SetPrimaryDomainToSelf()
{
_primaryDomain = AppDomain.CurrentDomain;
}

/// <summary>
/// Determines whether this is the primary domain.
/// </summary>
/// <value>
/// <see langword="true"/> if this instance is the primary domain; otherwise, <see langword="false"/>.
/// </value>
public static bool IsPrimaryDomain
{
get
{
return _primaryDomain == AppDomain.CurrentDomain;
}
}

/// <summary>
/// Creates the initial domain.
/// </summary>
/// <param name="friendlyName">Name of the friendly.</param>
/// <param name="securityInfo">The security info.</param>
/// <param name="appDomainInfo">The AppDomain setup info.</param>
/// <returns></returns>
public static AppDomain CreateInitialDomain(string friendlyName, Evidence securityInfo, AppDomainSetup appDomainInfo)
{
if (AppDomain.CurrentDomain.DomainManager is PrimaryAppDomainManager)
return null;

appDomainInfo = appDomainInfo ?? new AppDomainSetup();
appDomainInfo.AppDomainManagerAssembly = typeof(PrimaryAppDomainManager).Assembly.FullName;
appDomainInfo.AppDomainManagerType = typeof(PrimaryAppDomainManager).FullName;

var appDomain = AppDomainManager.CreateDomainHelper(friendlyName, securityInfo, appDomainInfo);
((PrimaryAppDomainManager)appDomain.DomainManager).SetPrimaryDomainToSelf();
_primaryDomain = appDomain;
return appDomain;
}

/// <summary>
/// Returns a new or existing application domain.
/// </summary>
/// <param name="friendlyName">The friendly name of the domain.</param>
/// <param name="securityInfo">An object that contains evidence mapped through the security policy to establish a top-of-stack permission set.</param>
/// <param name="appDomainInfo">An object that contains application domain initialization information.</param>
/// <returns>A new or existing application domain.</returns>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="ControlEvidence, ControlAppDomain, Infrastructure"/>
/// </PermissionSet>
public override AppDomain CreateDomain(string friendlyName, Evidence securityInfo, AppDomainSetup appDomainInfo)
{
appDomainInfo = appDomainInfo ?? new AppDomainSetup();
appDomainInfo.AppDomainManagerAssembly = typeof(PrimaryAppDomainManager).Assembly.FullName;
appDomainInfo.AppDomainManagerType = typeof(PrimaryAppDomainManager).FullName;

var appDomain = base.CreateDomain(friendlyName, securityInfo, appDomainInfo);
((PrimaryAppDomainManager)appDomain.DomainManager).SetPrimaryDomain(_primaryDomain);

return appDomain;
}
}

并且您需要稍微更改您的Main()(应用程序入口):

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
new Program().Run(args);
}

void Run(string[] args)
{
var domain = PrimaryAppDomainManager.CreateInitialDomain("PrimaryDomain", null, null);
if (domain == null)
{
// Original Main() code here.
}
else
{
domain.CreateInstanceAndUnwrap<Program>().Run(args);
}
}

现在您可以随时获取 PrimaryAppDomainManager.PrimaryDomain 以获取对主域的引用,请记住它不是由 .Net 运行时创建的初始域 - 它是我们创建的立即。

可以看看我的blog post里的评论获取 .Net 运行时使用 app.config 自动为您 Hook 的方法。

编辑:我忘了添加我使用的扩展方法,这里是:

/// <summary>
/// Creates a new instance of the specified type.
/// </summary>
/// <typeparam name="T">The type of object to create.</typeparam>
/// <param name="appDomain">The app domain.</param>
/// <returns>A proxy for the new object.</returns>
public static T CreateInstanceAndUnwrap<T>(this AppDomain appDomain)
{
var res = (T)appDomain.CreateInstanceAndUnwrap(typeof(T));
return res;
}

关于c# - 如何获取父 AppDomain?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7120866/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com