sti*_*ijn 7 c# serialization prism system.type
我有一个a.exe运行良好的应用程序并加载了一个程序集b.dll,如果重要的话,这是一个Prism模块.此dll是从不在路径中但a.exe位于所在目录中的目录加载的.
装配由Prism完成,并设置如下:
public class MyModuleCatalog : ComposablePartCatalog
{
private readonly AggregateCatalog _catalog;
public MyModuleCatalog()
{
//directory Modules is not in the path, but all
//dependencies of b.dll are, so b.dll gets loaded fine
var asmCat = new AssemblyCatalog( "Modules/b.dll" );
_catalog.Catalogs.Add( asmCat );
}
public override IQueryable<ComposablePartDefinition> Parts
{
get { return _catalog.Parts; }
}
}
class BootStrapper : MefBootstrapper
{
....
protected override void ConfigureAggregateCatalog()
{
base.ConfigureAggregateCatalog();
AggregateCatalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
AggregateCatalog.Catalogs.Add( new MyModuleCatalog() );
}
....
}
Run Code Online (Sandbox Code Playgroud)
在b.dll有一个类ImInB:
[Export]
public class ImInB
{
public void DoIt()
{
try
{
var stream = new MemoryStream();
//using System.Runtime.Serialization.Formatters.
var formatter = new BinaryBinaryFormatter();
//serialize our type
formatter.Serialize( stream, this.GetType() );
//get it back
stream.Position = 0;
var obj = formatter.Deserialize( stream ); //this throws??
}
catch( Exception e )
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
这只是示例代码,是加载/保存设置到数据库的持久框架的一部分.对象的类型始终是序列化的,并且充当数据库的键.在反序列化时,将对类型作为对要加载的对象的双重检查进行检索.该函数从a.exe以下方式调用:
container.GetExportedValue<ImInB>().DoIt();
Run Code Online (Sandbox Code Playgroud)
反序列化类型时抛出的异常(之前已成功序列化两行)是:
"Could not load file or assembly 'b.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
or one of its dependencies. The system cannot find the file specified."
Run Code Online (Sandbox Code Playgroud)
问题:
Deserialize 嘿,dll已经加载了,不去寻找它更新 我的第二个问题基本上由Felix K回答; 以下代码修复了该问题:
public static class AssemblyResolverFix
{
//Looks up the assembly in the set of currently loaded assemblies,
//and returns it if the name matches. Else returns null.
public static Assembly HandleAssemblyResolve( object sender, ResolveEventArgs args )
{
foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() )
if( ass.FullName == args.Name )
return ass;
return null;
}
}
//in main
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolverFix.HandleAssemblyResolve;
Run Code Online (Sandbox Code Playgroud)
这也证明了程序集是有效加载的,包括它的所有依赖项,所以第一个问题仍然存在:对我来说,为什么框架本身无法解决这个问题,这是一种谜.此外,我不能在使用大致相同结构的第二个应用程序中重现它.
我不知道为什么在dll已经加载时会发生这种情况,但我认为这与序列化本身无关,对我来说它看起来像是一个.NET错误.
这可能会帮助你,或指出你正确的方向:
AppDomain current = AppDomain.CurrentDomain;
current.AssemblyResolve += new ResolveEventHandler(HandleAssemblyResolve);
static Assembly HandleAssemblyResolve(object sender, ResolveEventArgs args)
{
/* Load the assembly specified in 'args' here and return it,
if the assembly is already loaded you can return it here */
}
Run Code Online (Sandbox Code Playgroud)
每当缺少dll时,都会调用resolve方法,因此当你的dll丢失时也会发生这种情况.dotNET找不到它,因为它位于"Modules"文件夹中,因此您必须自己解析引用.
| 归档时间: |
|
| 查看次数: |
1852 次 |
| 最近记录: |