Why castle.windsor injecting dll more than once - c#

I'm using castle.windsor version 3.3 for .net 3.5.
I have a weird issue,
It seems my app loads dll more than once.
i'm loading the assembly with:
WindsorContainer().Install(FromAssembly.Named([AssemblyName]);
When I check the container's nodes (after the registration), every assembly have only one occurrence,
but when i check what dll my application is loading (via process explorer),
I can see same dll more than once, with the same version and path.
Also, i want to add that my application works just fine,
but loading dll multiple time is not a normal behavior.
thanks.

Related

Asp.net loads all dlls on startup causing BadImageFormatException

I have an ASP .NET 4.0 project which depends on two native dlls, lets call them Native.Lib.dll and Native.Lib64.dll (32 and 64 bit respectively). Our project is built as AnyCPU and we dynamically load one of the two native libs based on the value of IntPtr.Size.
The native libraries are installed same directory as the rest of the binaries. Whenever I run the project, I get:
BadImageFormatExceptionCould not load file or assembly 'Native.Lib64'
or one of its dependencies. An attempt was made to load a program with
an incorrect format.
And when I switch IIS to 64 bit, it has the same complaint about 'Native.Lib'. From the research I have done, it looks like ASP.net loads all dlls in the directory on startup and blows up because of a "bitness" mismatch.
I have found that I can remove these binaries from the initial load in the Web.config file using <remove assembly="Native.Lib"/> and <remove assembly="Native.Lib64"/>, but I am worried that when it comes time to load these assemblies, they won't be able to load.
Furthermore, there are two other native assemblies already in the directory that ASP.net doesn't seem to have a problem with. (the developer that already solved this problem is no longer with the company). There are no <remove> tags in the config file for them, but ASP doesn't seem to mind.
Is there a way I can get ASP.net to ignore these files without removing them? If not, will the dlls be available when I call Assembly.LoadFile()?

MVC4: Is there a way to run codes even before the core assembly loaded?

I would like to run codes before even the main / core assembly (the project assembly) is being loaded into the server.
I want to run such as copy assembly code, which copy the updated assembly for the main application. So I want to copy the latest one then load that, after that all the referenced assembly follows. I want to do it from code / automatically every time the application is starting.
Is there a way to do that?

Unloadable plugins leak assemblies in Mono

I'm implementing a plugin system which allows them to be reloaded without restarting the host process. Everything works flawlessly in .NET 4.5 but when running in Mono 3.2.7 the plugin assembly gets leaked into the host AppDomain and the plugin can not be changed.
The assembly gets loaded into the host AppDomain when calling AppDomain.CreateInstanceFromAndUnwrap to create an instance of a type in the plugin assembly. This shouldn't cause problems because the type inherits MarshalByRefObject and shares a common interface.
You can see my code here: https://github.com/Rohansi/PluginTest The line which causes the assembly to leak is here.
I found a workaround for this issue. I've updated the Github repo with the fixes but I'll sum it up here.
To prevent leaking the assembly into the host AppDomain the assembly must not be in one of the locations the runtime will search for it. You either need to load it in a subdirectory or load it under a different file name. The assembly will no longer be automatically loaded into the host AppDomain but it started crashing when reloading.
I fixed this crash by replacing CreateInstanceFromAndUnwrap calls with this method. The PluginBridge instance is still created with CreateInstanceFromAndUnwrap.
After all this it seems I have working plugin reloading in both .NET and Mono (tested in 3.4).

MEF Different Assembly Version Loading Issue

I have a bit of a conundrum with MEF.
I have an installer and configuration application shell which uses MEF to load individual installer components. This gives an end user the ability to select from whatever components have been placed into the install distributable.
The first install components which were written to use this used version 11 of SQLServer SMO libraries. Installing against either 2008R2 or 2012 works fine. (lets call this component A)
I have another team migrating code to a new component but that code uses version 10 of the SQLServer SMO, RMO, and SSIS (DTS) libraries. (lets call this component B)
When MEF goes to load component B I get a LoaderExceptionFailure for one of the SQLServer DLLs (Microsoft.SqlServer.Replication). It actually gives a FileNotFoundException (listing the DLL). The DLL exists in the component's directory. It is the correct version 10.
The shell application already has version 11 files in it.
Is there a way I can tell the application context what to do? Is there a way I can tell the component to load any specific libraries it needs?
I want to assume that each component can specify something "Associated.Library, Version=1.0.0.0, publickey=abcdef123456789, culture=none".
The reason the CLR (not MEF) cannot find the assembly is because it is neither in the GAC, not in the places were the current AppDomain is setup to probe for assemblies.
One way to deal with this kind of problem is to add the missing assembly to the GAC.
Another approach is to add the folder containing the missing assembly to the probing paths of your application. If you don't mind deploying these assemblies in the application base folder (the one containing your executable) then do so. Otherwise you can add deploy it in a sub folder of your application base folder and add the folder to the privatePath element of your app.config.
You will find more information on the article: How the Runtime Locates Assemblies.

Loading C# DLL to C++/CLI - dependencies directory

I wrote a dll c++/cli library which uses my other c# dll library. C++/cli library works fine when I've got c# dll in the same folder as application which calls it. This library will be finally loaded to many applications and a C# dll must not be copied into directory with application. It has to be in the same folder as c++/cli library, but in that cases I've got System.IO.FileNotFoundException.
My suggestion is to load c# library manually or to change path where f.ex. firefox is looking for dependencies, but I tried with LoadLibrary() and Assembly::LoadFrom() methods to force loading from right directory. Of course I added directory path with dll to system PATH.
I work on VS2010.
You don't change the default directory where an application will look for dlls.
At design time put your dll in some well know location, the one you are going to deploy to. Add a reference to it, make sure it's set to Don't copy ever, otherwise it will end up in the bin folder. You have to do this otherwise it won't compile.
When you deploy, you'll need one package to deploy common dlls, and one for each application. Careful you don't create your own version of dll hell, if appA needs an older or new version of the common dll, compared to AppB
Add an AppDomain.AssemblyResolve event to main (for windows app). At run time the event handler will get fired when you reference a type in your dll, and the assembly has not yet been loaded.
In there you load it from the well known location. That usually in config, or in a relative path.
E.g.
AllMyApps
CommonDLLS
MyFirstApp
So the path you load the required common dll from would be "..\CommonDlls\MyCommondll.dll".
NB you will want to secure the dlls in some way, otherwise a bad guy might be able to inject their version of one in to your app, which would be bad...
You can use this mechanism to get the dll from a remote server or a database blob as well.
The simplest case is only a few lines of code, just look the event up. Took me about 15 minutes to get this going in a similar scenario.
Not on this machine though, otherwise I'd have pasted in the code.

Categories