InvalidOperationException when Injected DLL is not in \bin

Jan 30, 2009 at 1:58 PM
Edited Jan 30, 2009 at 2:09 PM

The background for this is almost identical to that in post Project References when using Unity, so I'm going to copy the description from there.

Consider these Projects:
- Website
- BusinessLogic
- DataAccessInterfaces
- DataAccessADO
- DataAccessEntityFramework

MainSolution.sln >> includes all projects
DataAccessSolution.sln >> includes DataAccessInterfaces, DataAccessADO and DataAccessEntityFramework projects, plus Test projects for unit testing.

BusinessLogic has a reference to DataAccessInterfaces.  Unity is used to determine if a class from DataAccessADO or DataAccessEntityFramework is returned and used.

Because BusinessLogic does not have a reference to DataAccessADO or DataAccessEntityFramework, those DLLs are not copied to the website /bin automatically. 

Now this is where our situation diverges.  We have our concrete implementations of the DataAccessADO and DataAccessEntityFramework built and copied into a common directory (e.g. C:\MyCompany\CommonBinaries).  This directory is included in PATH (the operating system environment variable).  We'd thought that Unity would check the \bin, the GAC, and the look in the directories in PATH to find the concrete DLL to inject, but instead we get the following:

[InvalidOperationException: The current type, log4net.ILog, is an interface and cannot be constructed. Are you missing a type mapping?]

We've proved that this is because the concrete DLL is not in the \bin for the web project.  Primary Question: Is there some way that we can tell Unity to look in the PATH directories?

There's another oddity here, too.  We're actually injecting a dependency / type that is not the log4net.ILog that shows up in the exception.  log4net.ILog is a sub-dependency of the type we're trying to load.  Secondary Question:  can anyone explain this?

Jan 30, 2009 at 3:02 PM
[quote]
We've proved that this is because the concrete DLL is not in the \bin for the web project.  Primary Question: Is there some way that we can tell Unity to look in the PATH directories?
[/quote]

For the frameworks and projects I've worked on where we were deploying assemblies in sub-directories, I we added a hook in the AppDomain to the Resolve event and had it load the assembly manually when the framework looked for it.

As for the second question, I'm not sure what you're asking. Unity will do a recursive resolve and fail if all dependencies on any sub objects cannot be resolved. Also remember that an assembly load doesn't necessarily register types in the container. If the type hasn't been configured to be registered as the given interface or type it cannot be resolved.
Jan 30, 2009 at 4:19 PM

dp,

When you say "sub-directories", do you mean directories under the \bin?

Our structure looks something like this:

C:
   \Inetpub
        \MyWebApp
            \bin
                MyWebPage.xxx
                BusinessLogic.DLL
                DataAccessInterfaces.DLL

D:
    \CommonDir
        DataAccessADO.DLL
        DataAccessEntityFramework.DLL

Does your AppDomain Resolve hook handle that situation?  Executing app from C:\Inetpub\MyWebApp\bin and finding the DLLs in D:\CommonDir ?

 

Jan 30, 2009 at 6:00 PM
Unity does not do assembly loading. All it does is ask the framework to do it. As such, all the normal .NET rules and techniques apply.