gpt4 book ai didi

C# 程序集在子域中创建实例

转载 作者:太空宇宙 更新时间:2023-11-03 15:44:54 25 4
gpt4 key购买 nike

我正在尝试创建一个插件框架并通过 C# 中的反射加载依赖项。我当前的实现如下:

public interface IPlugin : IDisposable
{
void Run();
}

public interface IPluginProxy : IDisposable
{
void RunProxy();
void LoadDependencies(string pluginDirectoryPath, AppDomain pluginDomain);
}

public class PluginProxy : MarshalByRefObject, IPluginProxy, IDisposable
{
private List<IPlugin> pluginTypes = null;


public void ProcessProxy()
{
//loop thorough plugin types and call Run on all plugins
foreach(var pluginType in pluginTypes)
{
pluginType.Run();
}
}

public void LoadDependencies(string pluginDirectoryPath, AppDomain pluginDomain)
{
pluginTypes = Utility.LoadAssembliesAndGetPluginTypes(pluginDirectoryPath, pluginDomain);
}

//TODO:
public void Dispose(){}

}

public Class Utility
{
public static List<IPlugin> LoadAssembliesAndGetPluginTypes(string pluginDirectoryPath, AppDomain pluginDomain)
{
try
{
var pluginTypes = new List<IPlugin>();
var pluginsDirectory = new DirectoryInfo(pluginDirectoryPath);
var files = pluginsDirectory.GetFiles("*.dll", SearchOption.TopDirectoryOnly);

foreach (FileInfo file in files)
{
// Load the assembly into the child application domain.
Assembly assembly = pluginDomain.Load(AssemblyName.GetAssemblyName(file.FullName));
var iPluginTypes = zGetTypes(assembly);
pluginTypes.AddRange(iPluginTypes.ToList());
}

return pluginTypes;
}
catch (Exception ex)
{
throw ex;
}
}

private static IEnumerable<IPlugin> zGetTypes(Assembly assembly)
{
var myPlugins = from y in assembly.GetTypes()
where y.IsClass && y.GetInterface("IPlugin") != null &&
y.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(y) as IPlugin;
return myPlugins;
}
}

我有一个创建新应用程序域的 Windows 服务。然后它获取 PluginProxy 并调用 LoadDependencies 和 ProcessProxy。请注意,我正在尝试将依赖项加载到子域中。

问题出在 zGetTypes 方法上。该方法能够找到 IPlugin 类型(智能感知显示)。但是,即使调用 Activator.CreateInstance,类型也不会初始化(null)。

请注意,如果我在子域中,zGetTypes 无法创建 IPlugin 类型的实例。

程序集 assembly = pluginDomain.Load(AssemblyName.GetAssemblyName(file.FullName));

如果我不创建单独的应用程序域,而只是将程序集加载到主应用程序域中,则可以创建实例。在我的例子中,Service 的 appdomain 创建了子 appdomain。我想将加载插件程序集的责任推给代理。 Proxy 派生自 MarshalByRefObject,因此我可以创建一个实例并从 Windows 服务端解包它。

服务然后将插件的加载和生命周期管理委托(delegate)给代理。代理将通过 LoadDependencies 的方法参数获取子应用程序域的上下文。

知道为什么不创建 IPlugin 实例吗?

最佳答案

我能够通过在代理级别推断域来解决问题。在我的 Windows 服务中,我按照以下方式创建插件代理实例:

IPluginProxy pluginProxy = IPluginProxy)
(pluginDomain
.CreateInstanceFromAndUnwrap(directory.FullName + "\\Utility.Common.dll",
typeof(PluginProxy).FullName));

在调用 LoadAssemblies 时,我将子应用程序域作为参数传递:LoadDependencies(string pluginDirectoryPath, AppDomain pluginDomain);

这是不必要的,因为代理在子域的上下文中。这解决了问题。

关于C# 程序集在子域中创建实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28529835/

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