AssemblyResolve не запускается для зависимостей
Сейчас я боюсь события AssenblyResolve. Я искал stackoverflow и сделал другой поиск в Google и пробовал все, что, по моему мнению, было актуальным. Вот ссылки, которые ближе к моей проблеме (на мой взгляд):
У меня есть класс Bootstrapper со статическим методом (я удалю код безопасности потока, который у нас есть, только для ясности:
public static void Initialize()
{
AppDomain.CurrentDomain.AssemblyResolve += CustomResolve;
}
private static Assembly CustomResolve(object sender, ResolveEventArgs args)
{
// There is a lot code here but basicall what it does.
// Is determining which architecture the computer is running on and
// extract the correct embedded dll (x86 or x64). The code was based
// on milang on GitHub (https://github.com/milang/P4.net). And it the same
// purpose we want to be able to load the x86 or x64 version of the perforce dll
// but this time with the officially Perforce supported p4api.net.
// Once the dll is extracted we assign it to the boostrapper
Bootstrapper._p4dnAssembly = Assembly.LoadFile(targetFileName);
// Make sure we can satisfy the requested reference with the embedded assembly (now extracted).
AssemblyName reference = new AssemblyName(args.Name);
if (AssemblyName.ReferenceMatchesDefinition(reference, Bootstrapper._p4dnAssembly.GetName()))
{
return Bootstrapper._p4dnAssembly;
}
}
Мне удалось заставить код работать, если у меня есть простой класс с основным методом и статическим конструктором. Статический конструктор просто вызывает метод Boostrapper.Initialize().
После этого я мог использовать свою библиотеку, и она работала так, как ожидалось:
public static class Test
{
static Test()
{
Bootstrapper.Initialize();
}
public static void Main()
{
// Using the library here is working fine. The AssemblyResolve event was
// fired (confirmed by a breakpoint in Visual Studio)
}
}
Проблема заключается в том, что есть хотя бы один уровень зависимости. В основном код остается тем же, но на этот раз мой код библиотеки находится внутри другой библиотеки:
public static class Test
{
static Test()
{
Bootstrapper.Initialize();
}
public static void Main()
{
Class1 myClass = new Class1();
// The following line is using the code of the extracted library, but
// The AssemblyResolve event is not fired (or fired before I register the
// callback) and therefore the library is not found : result
// BadImageFormatException() error could not load libary because one
myClass.Connect();
}
}
Похоже на # 2 ссылок, которые я ранее говорил, объясняет, что я вижу, но это не работает. Точка прерывания Visual Studio на обратном вызове AssemblyResove никогда не ударяется.
Любая идея о том, что происходит?
Фрэнсис
Ответы
Ответ 1
Кто-то ответил, но ответ был удален. Поэтому я не могу отметить это как ответ.
В основном работает тот факт, что код не должен находиться за пределами "основного" метода.
Исходя из нового проекта, решите проблему, поэтому я предполагаю, что у меня возникли некоторые проблемы с dll (возможно, x86 dll в папке x64 или наоборот)
static void main(string[] args)
{
Boostrapper.Initialize();
RealMain();
}
static void RealMain()
{
Class1 myClass = new Class1();
myClass.Connect();
}
Ответ 2
Я знаю, что прошло некоторое время, так как этот вопрос задавали и отвечали, но я хотел все-таки добавить мое решение по этому вопросу (поскольку я просто потратил несколько часов на это, возможно, благодаря этому кому-то еще не пришлось бы )
Проблема в основном заключается в том, что приложение пытается разрешить все сборки, необходимые для выполнения метода в начале этого метода:
static void main(string[] args)
{
// <-- here the app tries to resolve MyAssembly
// and as MyAssembly.Class1 is not found, the app crashes
// this next line is never called:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
// class contained in an assemnly that we need to resolve
MyAssembly.Class1 myClass = new MyAssembly.Class1();
}
Вот почему вышесказанное выйдет из строя: обработчик события ResolveAssembly никогда не будет вызван, потому что он никогда не подключался.
И это также то, почему работает нижеследующее решение (как опубликовано OP):
static void main(string[] args)
{
Initialize();
RealMain();
}
static void Initialize()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
}
static void RealMain()
{
// <-- here the app tries to resolve MyAssembly
// class contained in an assemnly that we need to resolve
MyAssembly.Class1 myClass = new MyAssembly.Class1();
// and everything is OK
}