У меня есть приложение 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() );
}
....
}
В 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 )
{
}
}
}
Это просто пример кода и часть постоянной структуры, которая загружает / сохраняет настройки в базе данных. Тип объекта всегда сериализуется и служит ключом к базе данных. После десериализации тип возвращается в качестве двойной проверки для загружаемого объекта.
Функция вызывается из a.exe
:
container.GetExportedValue<ImInB>().DoIt();
Исключение, возникающее при десериализации типа (который был успешно сериализован двумя строками ранее):
"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."
Вопросы:
Deserialize
эй, что dll уже загружена, не ищите ее ОБНОВЛЕНИЕ на мой второй вопрос в основном отвечает Феликс К. следующий код устраняет проблему:
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;
Это также доказывает, что сборка эффективно загружена, включая все ее зависимости, поэтому остается первый вопрос: для меня загадка, почему фреймворк не может понять это самостоятельно. Более того, я не могу воспроизвести его во втором приложении, использующем примерно такую же структуру.