c# - AppDomain.CurrentDomain.AssemblyResolve issues -
i have a single application loads dynamicaly 3 following solutions:
- solutiona references x.dll version 3 z.dll version 1 references x.dll version 1 - solutionb references x.dll version 2 - solutionc references x.dll version 1
.
x.dll contains xaml (depending on dll version change text, background , foreground) :
<usercontrol x:class="x.mainwindow" background="dodgerblue"> <usercontrol.content> <label foreground="black" content="version 1" /> </usercontrol.content> </usercontrol>
.
z.dll contains xaml uses x.dll :
<usercontrol x:class="z.zmainwindow"> <stackpanel> <x:mainwindow /> </stackpanel> </usercontrol>
.
solutiona displays x version 3 , z version 1 (which displays x version 1)
solutionb displays x version 2
solutionc displays x version 1
.
what want always use higher version of assembly, mean solutiona, solutionb , solutionc must always use x.dll in version 3.
here code use 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 => == args.name) != null) { // assembly has 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; }
.
everything works until in name controls
i.e. (in z.dll) : <label foreground="black" content="version 1" />
becomes <label foreground="black" content="version 1" x:name="labelv1" />
and (in x.dll) : <x:mainwindow x:name="xmainwindow" />
becomes <x:mainwindow x:name="xmainwindow" />
at points, solutiona has exception , not displayed when solutiona loaded before solutionc (solutionb never problem , solutionc loaded before solutiona, works perfectly).
what see, when attached appdomain.currentdomain.assemblyload += currentdomain_assemblyload
xamls automaticaly loads assembly need :
solutionc's xaml loads x in version 1 solutiona's xaml loads x in version 3 solutiona's xaml loads z in version 1
then see following exception in xaml.cs:
an exception of type 'system.exception' occurred in presentationframework.dll not handled in user code additional information: component 'x.mainwindow' not have resource identified uri '/x;component/mainwindow.xaml'.
and following 1 in xaml:
exception thrown: 'system.windows.markup.xamlparseexception' in presentationframework.dll additional information: 'the invocation of constructor on type 'x.mainwindow' matches specified binding constraints threw exception.' line number '10' , line position '10'.
.
do have leads avoid issue ?
Comments
Post a Comment