Проблемы с AppDomain.CurrentDomain.AssemblyResolve
У меня есть одно приложение, которое динамически загружает три следующих решения:
- SolutionA which references
X.dll version 3
Z.dll version 1 which references
X.dll version 1
- SolutionB which references
X.dll version 2
- SolutionC which references
X.dll version 1
,
X.dll содержит некоторые XAML (в зависимости от версии DLL я изменяю текст, фон и передний план):
<UserControl x:Class="X.MainWindow"
Background="DodgerBlue">
<UserControl.Content>
<Label Foreground="Black" Content="version 1" />
</UserControl.Content>
</UserControl>
,
Z.dll также содержит некоторые XAML, которые используют X.dll:
<UserControl x:Class="Z.ZMainWindow">
<StackPanel>
<X:MainWindow />
</StackPanel>
</UserControl>
,
SolutionA отображает версию X 3 и версию 1 Z (которая отображает версию 1 X)
SolutionB отображает версию X 2
SolutionC отображает X версию 1
,
Я хочу всегда использовать более высокую версию сборки, что означает, что SolutionA, SolutionB и SolutionC всегда должны использовать X.dll в версии 3.
Вот код, который я использую для AssemblyResolve:
private static Assembly OnAssemblyResolveWithDllPaths(object sender, ResolveEventArgs args)
{
try
{
AssemblyName parsedName = new AssemblyName(args.Name);
Version currentVersion = parsedName.Version;
string currentName = parsedName.Name;
string currentCulture = parsedName.CultureName;
byte[] currentPublicKeyToken = parsedName.GetPublicKeyToken();
string assemblyPath = string.Empty;
if (loadedAssemblies.FirstOrDefault(a => a == args.Name) != null)
{
// Assembly has already been loaded
return null;
}
List<string> possibleAssembliesPaths = m_dllPaths.Where(d => d.Contains(parsedName.Name)).ToList();
if (possibleAssembliesPaths != null && possibleAssembliesPaths.Count > 0)
{
if (possibleAssembliesPaths.Count == 1)
{
assemblyPath = possibleAssembliesPaths[0];
}
else
{
foreach (string possibleAssembly in possibleAssembliesPaths)
{
if (File.Exists(possibleAssembly))
{
AssemblyName possibleAssemblyName = AssemblyName.GetAssemblyName(possibleAssembly);
Version possibleVersion = possibleAssemblyName.Version;
string possibleName = possibleAssemblyName.Name;
string possibleCulture = possibleAssemblyName.CultureName;
byte[] possiblePublicKeyToken = possibleAssemblyName.GetPublicKeyToken();
if (currentName == possibleName
&& currentCulture == possibleCulture
&& currentPublicKeyToken.SequenceEqual(possiblePublicKeyToken)
&& currentVersion < possibleVersion)
{
assemblyPath = possibleAssembly;
currentVersion = possibleAssemblyName.Version;
currentName = possibleAssemblyName.Name;
currentCulture = possibleAssemblyName.CultureName;
currentPublicKeyToken = possibleAssemblyName.GetPublicKeyToken();
}
}
}
}
if (!string.IsNullOrEmpty(assemblyPath))
{
loadedAssemblies.Add(args.Name);
return Assembly.LoadFrom(assemblyPath);
}
}
}
catch
{
return null;
}
return null;
}
,
Все работает отлично, пока на имя моего контроля
т.е. (в Z.dll): <Label Foreground="Black" Content="version 1" />
становится <Label Foreground="Black" Content="version 1" x:Name="LabelV1" />
и (в X.dll): <X:MainWindow x:Name="XMainWindow" />
становится <X:MainWindow x:Name="XMainWindow" />
На этом этапе SolutionA имеет исключение и не отображается, когда SolutionA загружается до SolutionC (SolutionB никогда не является проблемой, и как только SolutionC загружается до SolutionA, все работает отлично).
Что я вижу, когда я привязан к AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad
является то, что XAML автоматически загружает сборку, в которой они нуждаются:
SolutionC's XAML loads X in version 1
SolutionA's XAML loads X in version 3
SolutionA's XAML loads Z in version 1
Затем я вижу следующее исключение в xaml.cs:
An exception of type 'System.Exception' occurred in PresentationFramework.dll but was not handled in user code
Additional information: The component 'X.MainWindow' does not have a resource identified by the URI '/X;component/mainwindow.xaml'.
и следующий в xaml:
Exception thrown: 'System.Windows.Markup.XamlParseException' in PresentationFramework.dll
Additional information: 'The invocation of the constructor on type 'X.MainWindow' that matches the specified binding constraints threw an exception.' Line number '10' and line position '10'.
,
Есть ли у вас ведет, чтобы избежать проблемы?