我正在尝试使用mef创建一个POC,我需要在一个准备好运行的项目中动态加载dll,为此我创建了一个控制台应用程序项目和一个类库
项目.
控制台应用程序项目的代码如下 -
namespace MefProjectExtension
{
class Program
{
DirectoryCatalog catalog = new DirectoryCatalog(@"D:\MefDll", "*.dll");
[Import("Method1", AllowDefault = true, AllowRecomposition = true)]
public Func<string> method1;
static void Main(string[] args)
{
AppDomainSetup asp = new AppDomainSetup();
asp.ShadowCopyFiles = "true";
AppDomain sp = AppDomain.CreateDomain("sp",null,asp);
string exeassembly = Assembly.GetEntryAssembly().ToString();
BaseClass p = (BaseClass)sp.CreateInstanceAndUnwrap(exeassembly, "MefProjectExtension.BaseClass");
p.run();
}
}
public class BaseClass : MarshalByRefObject
{
[Import("Method1",AllowDefault=true,AllowRecomposition=true)]
public Func<string> method1;
DirectoryCatalog catalog = new DirectoryCatalog(@"D:\MefDll", "*.dll");
public void run()
{
FileSystemWatcher sw = new FileSystemWatcher(@"D:\MefDll", "*.dll");
sw.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.Size;
sw.Changed += onchanged;
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
Console.WriteLine(this.method1());
sw.EnableRaisingEvents = true;
Console.Read();
}
void onchanged(object sender, FileSystemEventArgs e)
{
catalog.Refresh();
Console.WriteLine(this.method1());
}
}
}
Run Code Online (Sandbox Code Playgroud)
满足进口的图书馆项目如下
namespace MefLibrary
{
public interface IMethods
{
string Method1();
}
public class CallMethods : IMethods
{
[Export("Method1")]
public string Method1()
{
return "Third6Hello";
}
}
}
Run Code Online (Sandbox Code Playgroud)
一旦我编译了库项目(MefLibrary)并将dll放在D:\ MefDll位置并第一次运行控制台应用程序,我将看到输出为
屏幕上的第三个6个
但是现在如果我更改了method1的实现并使其返回"third7hello"构建MEF库项目并替换为D:\ MefDll,而我的控制台应用程序正在运行onchanged处理程序,即使在调用目录刷新后在屏幕上打印 Third6hello 而不是third7hello
是否有人知道这是什么原因,如果是的话请帮忙.
DirectoryCatalog.Refresh
只会添加新的或删除现有的程序集.它不会更新程序集.一个粗略的解决方法是:
DirectoryCatalog.Refresh
.这将删除装配中包含的零件.DirectoryCatalog.Refresh
.这将添加程序集中包含的更新部件.注意:
AssemblyVersionAttribute
).这是必需的,因为当使用DirectoryCatalog.Refresh
实际组件移除零件时将不会卸载.只能在卸载整个应用程序域时卸载程序集.因此,如果DirectoryCatalog.Refresh
找到一个新的程序集,它将AssemblyCatalog
使用程序集文件路径创建一个.AssemblyCatalog
然后将调用Assembly.Load
加载程序集.但是此方法不会加载AssemblyName.FullName
与已加载的程序集具有相同的程序集.CompositionOption.IsThreadSafe
标志创建CompositionContainer .正如我所提到的,这是一种解决方法.另一种方法是下载MEF的源代码并使用DirectoryCatalog.cs作为您自己的目录编目实现的指南.
归档时间: |
|
查看次数: |
2904 次 |
最近记录: |