{"id":1613,"date":"2009-07-15T15:04:00","date_gmt":"2009-07-15T15:04:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2009\/07\/15\/clr-4-making-the-assemblyresolve-event-more-useful\/"},"modified":"2021-10-04T15:07:42","modified_gmt":"2021-10-04T22:07:42","slug":"clr-4-making-the-assemblyresolve-event-more-useful","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/clr-4-making-the-assemblyresolve-event-more-useful\/","title":{"rendered":"CLR 4: Making the AssemblyResolve event more useful"},"content":{"rendered":"<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><!--?xml:namespace prefix = o ns = \"urn:schemas-microsoft-com:office:office\" \/--><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\" face=\"Calibri\">In the introductory post on CLR Binder (&lsquo;<\/font><a href=\"http:\/\/blogs.msdn.com\/b\/dotnet\/archive\/2009\/01\/29\/understanding-the-binder-part-1.aspx\">Understanding the Binder &ndash; Part 1<\/a><font size=\"3\" face=\"Calibri\"><\/font><font size=\"3\"><font face=\"Calibri\">&rsquo;), we listed the set of steps that the CLR Binder follows, in order to locate an assembly and bind to it. On reading this, an obvious question comes to mind. What happens when all of these steps fail to locate the assembly? Does the binder simply quit looking? <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\" face=\"Calibri\">It eventually does, but not before firing the <\/font><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.appdomain.assemblyresolve.aspx\"><font size=\"3\" face=\"Calibri\">AssemblyResolve<\/font><\/a><font size=\"3\"><font face=\"Calibri\"> event. The user can register an event handler for the AssemblyResolve event and then load the assembly that was intended to be loaded in the first place (or execute some other code appropriately). <span>&nbsp;<\/span><span>&nbsp;<\/span><\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">The AssemblyResolve event itself has been around for a while now. So what&rsquo;s changed in CLR 4? Prior to CLR 4, if an assembly A has a reference to another assembly B, and an AssemblyResolve event occurs for the referenced assembly (in this case, B), there is no means to know the identity of the parent assembly (or the referencing assembly, or A). <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">Why is this problematic? Let&rsquo;s take this example. Let&rsquo;s assume that an assembly FirstParent.dll references Child.dll. Let&rsquo;s also assume SecondParent.dll also references Child.dll. On failing to load Child.dll, AssemblyResolve event is fired. <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">Now, while loading FirstParent.dll and SecondParent.dll using LoadFile(), an AssemblyResolve event is fired for Child.dll. Looking at the AssemblyResolve event, it is unclear as to which parent assembly actually triggered loading Child.dll. This is not helpful if the user wants to execute different code as a part of the ResolveEventHandler, depending on the parent assembly that caused attempting to load Child.dll. <span>&nbsp;<\/span><\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\" face=\"Calibri\">In CLR 4, the AssemblyResolve event provides richer information that includes the parent assembly&rsquo;s identity. <\/font><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.resolveeventargs_members(VS.100).aspx\"><font size=\"3\" face=\"Calibri\">System.ResolveEventArgs<\/font><\/a><font size=\"3\"><font face=\"Calibri\"> now has a property called <b>RequestingAssembly<\/b>, which is the assembly which requested the (unsuccessful) load of the child assembly, triggering an AssemblyResolve event. <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">With this new property, when AssemblyResolve event is fired, apart from the current assembly (which could not be located by the Binder), the parent assembly is also provided. <\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">Thus, using this property,<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">(a) The user now knows which assembly caused the load event <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\"><font face=\"Calibri\">(b) The event handler can now make use of the parent assembly that is passed.<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\"><font size=\"3\" face=\"Calibri\">You can read more about this new property <\/font><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.resolveeventargs.requestingassembly(VS.100).aspx\"><font size=\"3\" face=\"Calibri\">here<\/font><\/a><font size=\"3\"><font face=\"Calibri\">. <span>&nbsp;<\/span><\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 10pt\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; In the introductory post on CLR Binder (&lsquo;Understanding the Binder &ndash; Part 1&rsquo;), we listed the set of steps that the CLR Binder follows, in order to locate an assembly and bind to it. On reading this, an obvious question comes to mind. What happens when all of these steps fail to locate the [&hellip;]<\/p>\n","protected":false},"author":342,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[],"class_list":["post-1613","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet"],"acf":[],"blog_post_summary":"<p>&nbsp; In the introductory post on CLR Binder (&lsquo;Understanding the Binder &ndash; Part 1&rsquo;), we listed the set of steps that the CLR Binder follows, in order to locate an assembly and bind to it. On reading this, an obvious question comes to mind. What happens when all of these steps fail to locate the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/342"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=1613"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1613\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=1613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=1613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=1613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}