gpt4 book ai didi

c# - MEF + 插件未更新

转载 作者:太空狗 更新时间:2023-10-30 01:11:25 25 4
gpt4 key购买 nike

我已经在 MEF Codeplex 论坛上问过这个问题,但我还没有得到回复,所以我想我会试试 StackOverflow。如果有人感兴趣,这是原始帖子(这只是它的副本):

MEF Codeplex

“首先让我说,我对 MEF 完全陌生(今天才发现它),到目前为止我对它非常满意。但是,我遇到了一个非常令人沮丧的问题。我正在创建一个将具有插件架构的应用程序,插件将仅存储在单个 DLL 文件中(或编码到主应用程序中)。DLL 文件需要能够在运行时重新编译,应用程序应该识别这一点并且重新加载插件(我知道这很困难,但这是一项要求)。为了实现这一点,我采用了 http://blog.maartenballiauw.be/category/MEF.aspx 中介绍的方法(查找 WebServerDirectoryCatalog)。基本上,我的想法是“监控插件文件夹,复制新的/修改程序集到 Web 应用程序的/bin 文件夹并指示 MEF 从那里加载它的导出。”这是我的代码,这可能不是正确的方法,但它是我在网络上的一些示例中找到的:

        main()...
string myExecName = Assembly.GetExecutingAssembly().Location;
string myPath = System.IO.Path.GetDirectoryName(myExecName);
catalog = new AggregateCatalog();
pluginCatalog = new MyDirectoryCatalog(myPath + @"/Plugins");
catalog.Catalogs.Add(pluginCatalog);


exportContainer = new CompositionContainer(catalog);

CompositionBatch compBatch = new CompositionBatch();
compBatch.AddPart(this);
compBatch.AddPart(catalog);
exportContainer.Compose(compBatch);

    private FileSystemWatcher fileSystemWatcher;
public DirectoryCatalog directoryCatalog;
private string path;
private string extension;

public MyDirectoryCatalog(string path)
{
Initialize(path, "*.dll", "*.dll");
}

private void Initialize(string path, string extension, string modulePattern)
{
this.path = path;
this.extension = extension;
fileSystemWatcher = new FileSystemWatcher(path, modulePattern);
fileSystemWatcher.Changed += new FileSystemEventHandler(fileSystemWatcher_Changed);
fileSystemWatcher.Created += new FileSystemEventHandler(fileSystemWatcher_Created);
fileSystemWatcher.Deleted += new FileSystemEventHandler(fileSystemWatcher_Deleted);
fileSystemWatcher.Renamed += new RenamedEventHandler(fileSystemWatcher_Renamed);
fileSystemWatcher.IncludeSubdirectories = false;
fileSystemWatcher.EnableRaisingEvents = true;
Refresh();
}
void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
{
RemoveFromBin(e.OldName);
Refresh();
}
void fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e)
{
RemoveFromBin(e.Name);
Refresh();
}
void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
Refresh();
}
void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
Refresh();
}
private void Refresh()
{
// Determine /bin path
string binPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
string newPath = "";
// Copy files to /bin
foreach (string file in Directory.GetFiles(path, extension, SearchOption.TopDirectoryOnly))
{
try
{
DirectoryInfo dInfo = new DirectoryInfo(binPath);
DirectoryInfo[] dirs = dInfo.GetDirectories();
int count = dirs.Count() + 1;
newPath = binPath + "/" + count;
DirectoryInfo dInfo2 = new DirectoryInfo(newPath);
if (!dInfo2.Exists)
dInfo2.Create();

File.Copy(file, System.IO.Path.Combine(newPath, System.IO.Path.GetFileName(file)), true);
}
catch
{
// Not that big deal... Blog readers will probably kill me for this bit of code :-)
}
}
// Create new directory catalog
directoryCatalog = new DirectoryCatalog(newPath, extension);
directoryCatalog.Refresh();
}
public override IQueryable<ComposablePartDefinition> Parts
{
get { return directoryCatalog.Parts; }
}
private void RemoveFromBin(string name)
{
string binPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "");
File.Delete(Path.Combine(binPath, name));
}

所有这一切实际上都有效,在 main 中的代码结束后,我的 IEnumerable 变量实际上填充了 DLL 中的所有插件(如果您按照代码位于 Plugins/1 中,以便我可以修改dll 在插件文件夹中)。所以现在我应该能够重新编译插件 DLL,将其放入插件文件夹,我的 FileWatcher 检测到它已更改,然后将其复制到文件夹“2”并且 directoryCatalog 应该指向新文件夹。所有这些确实有效!问题是,尽管似乎每件事都指向正确的位置,但我的 IEnumerable 变量从未使用新插件进行更新。这么近,但又那么远!有什么建议么?我知道这样做的缺点,实际上没有 dll 被卸载并导致内存泄漏,但它是一个 Windows 应用程序,可能每天至少启动一次,而且插件不太可能改变经常如此,但客户仍然要求它在不重新加载应用程序的情况下执行此操作。谢谢!

感谢大家提供的任何帮助,无法解决这个问题让我发疯。”

最佳答案

没有触发重组,因为您的目录实现不提供通知。实现 INotifyComposablePartCatalogChanged解决这个问题。

关于c# - MEF + 插件未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2625475/

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