We typically only reference Microsoft.Practices.Unity.dll in our applications. We're only using basic capabilities, and this works fine. In one application, the act of using reflection is causing Unity to require another DLL.
For example, create a console app and reference only Microsoft.Practices.Unity (file version 2.0.414.0). Enter the following code and run it:
class Program
{
static void Main()
{
using (var container = new UnityContainer())
{
container.RegisterType<IDoSomething, ConcreteDoSomething>();
var thing = container.Resolve<IDoSomething>();
thing.DoSomething();
Console.WriteLine();
LoadSchemaLoaders();
}
}
public static void LoadSchemaLoaders()
{
var type = typeof(ISchemaLoader);
try
{
// Get all loaded assemblies, including Unity.
// Get all of the types.
// Filter for types that ISchemaLoader (custom type) can be assigned from.
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(c => type.IsAssignableFrom(c) && c.IsClass && !c.IsAbstract && !c.IsGenericParameter);
Console.WriteLine("Got here...");
types.FirstOrDefault();
}
catch (ReflectionTypeLoadException ex)
{
Console.WriteLine(ex.Message);
foreach (Exception exSub in ex.LoaderExceptions)
{
Console.WriteLine(exSub.Message);
}
}
}
}
public interface IDoSomething
{
void DoSomething();
}
public class ConcreteDoSomething : IDoSomething
{
public void DoSomething()
{
Console.WriteLine("Something!");
}
}
public interface ISchemaLoader {}
On my machine, the output is:
Something! Got here... Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. Could not load file or assembly 'Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Now comment out the line
LoadSchemaLoaders();
Run it again and it works.
This is a simplified version of production code. The production code is actually dynamically loading custom types that implement an interface. As soon as we introduced Unity, the code threw an exception. But Unity types can't implement our interface!
I don't understand how simply reflecting over the assembly is causing the core Unity assembly to require another dependency.
A type in the Unity assembly from an interface defined in Microsoft.Practices.ServiceLocation (probably IServiceLocator).
The compiler doesn't require your application to reference that dll directly...but reflecting over the System.Type object will try to load the dll referenced by Unity.
The reason this only happens when you reflect over the assembly is because Unity probably doesn't load the type that references Microsoft.Practices.ServiceLocation under normal circumstances.
As a work-around, you could enclose your Assembly.GetTypes() call in a try/catch block.
Alternatively, if you put the Microsoft.Practices.ServiceLocation dll in a location where your application can find it, that should resolve the issue as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With