Problem using Load from File... on Type Selector

Topics: Exception Handling Application Block
Nov 24, 2008 at 12:59 PM
Hi

I'm getting the following message when I try to add an assembly to the Type Selector by clicking on 'Load from File...' when using the Exception Handling Application Block.

---------------------------

---------------------------
Unable to load references for the specified assembly, please ensure all references are in the same directory as the assembly which is loaded.
---------------------------
OK  
---------------------------


I've read about the dwapi.dll issue so checked my dll using dependency walker (depends.exe) as I'm using Win XP and have IE7 installed. Dependency walker showed that there was a dependency on the dwapi.dll, so I downloaded a version of the dll from http://www.dll-files.com/dllindex/pop.php?dwmapi and now dependency walker says everthing is fine bar this message.

Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

I still get the "Unable to load references..." message regardless of having this dll in place. Could anyone please give me an idea of what I can do as I really don't want to uninstall IE7 or revert back to EntLib 4.0.

Many thanks
Jon

Nov 25, 2008 at 4:23 AM
Hi Jon,

At which point you got this error? Are you adding an assembly as a CustomExceptionType? is it a customhandler? Can you send you sample solution so i can repro.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Nov 25, 2008 at 12:04 PM
I've debugged the Enterprise Library 4.1 source code and found that if the dll I am loading is dependent on another dll that hasn't been loaded it brings up the "Unable to load references..." message, it would be nice at this point if it told you which dependencies were required or even better automatically loaded them if they are in the same folder as the dll been loaded as the message says!?, but it looks like the referenced assemblys are squirreled off to a temp folder.
The main problem is that if one of those dependencies doesn't have a class extended from System.Exception in the code of the assembly it never loads this assembly and therefore you are never able to load assemblies that are dependent on the assembly that has no System.Exception classes declared!!

I hope I have got this wrong somewhere as I'm surprised no one else has raised this, so any help would be much appreciated.

Jon

PS. A breakpoint in Microsoft.Practices.EnterpriseLibrary.Configuration.Design.TypeSelector.LoadTreeView(Assembly assembly)  ...... Line 212 should help find this.

 

Nov 25, 2008 at 1:13 PM
Determined the assembly is loaded that C:\EntLib41Src\Blocks\Configuration\Src\Design\TypeSelector.cs (line 281) assembly.getTypes() is creating a ReflectionTypeLoadException for but as a tmp123.tmp file in my local temp folder, as it is shown in AppDomain.CurrentDomain.GetAssemblies().
Where is GetTypes() looking for the loaded type as I can only assume it isn't in the current AppDomain?
Nov 26, 2008 at 7:33 AM
Hi,

The GetTypes() is looking for the types inside the assembly, in your case, the Assemblies that were retrieved by the AppDomain.CurrentDomain.GetAssemblies(), are those assemblies that are in the current execution context of your application. What do you mean by "for but as a tmp123.tmp file in my local temp folder", can you explain a bit more?


Thanks.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Nov 28, 2008 at 8:38 AM
Edited Nov 28, 2008 at 9:39 AM
Hi Valiant

Not my best English, I was trying to say that C:\EntLib41Src\Blocks\Configuration\Src\Design\TypeSelector.cs (line 281) assembly.getTypes() is raising a ReflectionTypeLoadException but the assembly that it is complaining about is in the AppDomain.CurrentDomain.GetAssemblies(). But, each time an assembly is loaded a copy is created and placed in my temp folder with a file format of tmp123.tmp where 123 is an incremented number.
I am suspicious this is why getTypes is not finding the assembly as none of the assemblies are in the GAC, but will investigate further.

Thanks for looking at this, and if I can supply you anymore info please give me a shout.

Jon
Dec 4, 2008 at 9:07 AM

Hi Jon,

Have you tried adding your assembly to GAC and load it from the type selector?

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 4, 2008 at 9:29 AM
Just tried it and still get the same issue, loaded it's dependencies into the GAC as well but still no joy. If you create a project with dependencies on other projects it is fairly straight forward to replicate. Just load up the dependent project in the type selector before you load up the the one it is dependent on.

Thanks
Jon





From: notifications@codeplex.com
To: jont73@hotmail.com
Date: Thu, 4 Dec 2008 02:07:38 -0800
Subject: Re: Problem using Load from File... on Type Selector [entlib:40626]


.ExternalClass { FONT-SIZE: 0.75em; FONT-FAMILY: Verdana } .ExternalClass #EC_ThreadNotificationFooter { BORDER-TOP: #ccc 1px solid; COLOR: gray } .ExternalClass #EC_ThreadNotificationPostBody { MARGIN-BOTTOM: 2em } .ExternalClass { FONT-SIZE: 0.75em; FONT-FAMILY: Verdana } .ExternalClass #EC_ThreadNotificationFooter { BORDER-TOP: #ccc 1px solid; COLOR: gray } .ExternalClass #EC_ThreadNotificationPostBody { MARGIN-BOTTOM: 2em } From: AvanadeSupport
Hi Jon,

Have you tried adding your assembly to GAC and load it from the type selector?
Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Read the full discussion online.
To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)
To start a new discussion for this project, email entlib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com
Dec 5, 2008 at 7:36 AM
Edited Dec 5, 2008 at 7:41 AM
I couldn't repro your error.  Here's my solution structure:
                     
    ClassLibrary1.csproj  -  references ClassLibrary2
        CustomException.cs  - inherits from Exception class and calls a certain method in CustomHandler class
    ClassLibrary2.csproj
        CustomHandler.csproj        
    ConsoleApplication1.csproj - references ClassLibrary1
        Program.cs  -  throws a CustomException and handles it using ExceptionPolicy.HandleException
 

I was able to configure an Exception Handling Block in ConsoleApplication1.csproj and define an Exception Policy for CustomException type. I was able to handle exceptions successfully. 
I suggest you enable fusion logs and use the Fuse Logs Viewer.exe to view assembly loading failures.
Link on how to enable fusion logs and use Fuse Logs Viewer: http://blogs.msdn.com/suzcook/archive/2003/05/29/57120.aspxhttp://msdn.microsoft.com/en-us/library/e74a18c4(VS.80).aspx


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Dec 5, 2008 at 8:14 AM
hi jont73,
were you editing config via Enterprise Library Configuration Tool from C:\EntLib41Src\EntLibConfig.exe or the one in the Start menu? maybe application is compiling mismatched copies of binaries.Will this post help? http://blogs.msdn.com/tomholl/archive/2007/04/19/avoiding-configuration-pitfalls-with-incompatible-copies-of-enterprise-library.aspx
Dec 16, 2008 at 4:52 PM
Edited Dec 16, 2008 at 4:57 PM
I am trying to make a new config file using the entLibConfig.exe application, and am having the same issue. Here is what is happening, the AssemblyLoader is copying the assembly we want to load into a temp file, all fine and dandy, however when it loades that assembly and cannot find the referenced assemblies, the AppDomain.AssemblyResolve event is not firing. Without that event firing there is no way for the AssemblyLoader to know to look for additional referenced assemblies. I have verified that the eventhandler is being created in the constructor.

/fake edit

As I was typing this, I did a little more debugging, the issue was caused by the using statement disposing of the AssemblyLoader before it tried to resolve the references. It was not resolving the references until method static Type[] LoadTypesFromAssembly(Assembly assembly) in the TypeSelector.cs.
I changed the code in the TypeSelectorUI.cs

From:
                        using (AssemblyLoader loaderHook = new AssemblyLoader(originalAssemblyFileName, referenceDirectory))
                        {
                            return Assembly.LoadFrom(loaderHook.CopiedAssemblyPath);
                        }

To:

                        using (AssemblyLoader loaderHook = new AssemblyLoader(originalAssemblyFileName, referenceDirectory))
                        {
                            Assembly loadedAssembly = Assembly.LoadFrom(loaderHook.CopiedAssemblyPath);
                            loadedAssembly.GetTypes();
                            return loadedAssembly;
                        }


this forces it to resolve the assembly references while the AssemblyLoader is still instantiated and the eventhandler for resolving assemblies is still active.
Dec 17, 2008 at 12:56 AM
Could you tell me exactly how to repro this error?


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com


Dec 17, 2008 at 3:05 AM
Sure, I was trying to build a validation block configuration. You have to have an assembly that references an assembly that is not in the GAC, similar to the project you have listed above. When you add a new Validation Configuration to an application, then try to add a type, click the "Load from File" button, and try to load the assembly that references the second non GAC assembly, in your case ClassLibrary2 from the project example above.
Dec 17, 2008 at 8:20 AM
Thanks, I was finally able to repro the error.  However, I'm not sure if this is a bug in entlib or this has something to do with how .net performs assembly loading because in our current project, one of my colleagues encounters this inconsistently.  I need to verify this first and I'll let you know.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Dec 17, 2008 at 9:07 AM
It has worked a couple of times for myself but never figured out why. Tried the fix liqdfire suggested and appeared to fix the problem, thanks liqdfire.

Guess a signed key patch for this will be out of the question. Would I be best adding my own signed key to it and using the new dll so I don't have to change to using the unsigned dll's?

Thanks again
Jon





From: notifications@codeplex.com
To: jont73@hotmail.com
Date: Wed, 17 Dec 2008 01:20:31 -0800
Subject: Re: Problem using Load from File... on Type Selector [entlib:40626]


.ExternalClass { FONT-SIZE: 0.75em; FONT-FAMILY: Verdana } .ExternalClass #EC_ThreadNotificationFooter { BORDER-TOP: #ccc 1px solid; COLOR: gray } .ExternalClass #EC_ThreadNotificationPostBody { MARGIN-BOTTOM: 2em } .ExternalClass { FONT-SIZE: 0.75em; FONT-FAMILY: Verdana } .ExternalClass #EC_ThreadNotificationFooter { BORDER-TOP: #ccc 1px solid; COLOR: gray } .ExternalClass #EC_ThreadNotificationPostBody { MARGIN-BOTTOM: 2em } From: AvanadeSupport
Thanks, I was finally able to repro the error. However, I'm not sure if this is a bug in entlib or this has something to do with how .net performs assembly loading because in our current project, one of my colleagues encounters this inconsistently. I need to verify this first and I'll let you know.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Read the full discussion online.
To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)
To start a new discussion for this project, email entlib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com
Dec 17, 2008 at 6:09 PM
Well calling it a bug could be debated on both sides. It looks like .Net is performing some type of lazy loading of the assembly, not completely walking the dependencies until a type is utilized out of the assembly, which could very well  have been an optimization added after the entlib was designed. However, with that being known now, one could argue that the manner in which entLib is preforming the assembly resolution for a dynamically loaded assembly does not coincide with that functionality, without forcing a dependency walk of the newely loaded assembly.

Overall, callit a bug, don't call it a bug makes no difference to me; however, I would like to see this fix, or some other fix for the problem in an upcoming release, or patch.

Jon, you are welcome, glad I could help with the issue.

- Chris -
Dec 31, 2008 at 8:23 AM
Just wanted to let you know that I've already added this in the issue tracker.
http://www.codeplex.com/entlib/WorkItem/View.aspx?WorkItemId=20410
It is indeed an EntLib bug as I didn't encounter it when I used the 4.0 version.

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 28, 2009 at 8:25 AM
This is a big issue, because it happens also at runtime when config file is manually edited. We tried to use a wrap handler on NHibernate.StaleObjectException and we are not able to use Enterprise Library because we got the error discussed here at runtime. Could you please put higher priority to the WorkItem 20410 ?

Thanks

Ivan
Feb 4, 2009 at 3:49 AM
Can't modify the workitem, no access to it.  Anyway you've already added your request there in the actual workitem so I think someone from Microsoft will be able to notice that, having that much votes.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

May 6, 2009 at 7:37 PM
Liqdfire's solution worked. Thanks very much for your time digging around!

A bit unreal that Microsoft hasn't sorted this one out yet... go open source - just fix it yourself instead of waiting for old Redmond to get around to it.


Sep 28, 2009 at 12:49 PM

Liqdfire solution worked for me too. Nice job!

Too bad the problem escaped unnoticed by Entlib developers.

May 12, 2010 at 12:12 PM
Edited May 12, 2010 at 12:43 PM

The fix did not work for me. I loaded the src files, changed everything stipulated and got build errors when I compiled. Since they were in projects I hadn't modified (?), I just rebuilt the project I did modify. But the type selection is still not working for me.

edit: On the upside, a low tech solution of going into the config and editing the xml by hand did the trick.  

May 13, 2010 at 1:27 AM

You can also try the workaround suggested by fsimonazzi.  Load first the referenced assemblies explicitly before loading the assembly you really need.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com