Normalmente solo hacemos referencia a Microsoft.Practices.Unity.dll en nuestras aplicaciones. Solo estamos usando capacidades básicas, y esto funciona bien. En una aplicación, el acto de usar la reflexión hace que Unity requiera otra DLL.La reflexión sobre los ensamblados provoca que Unity requiera Microsoft.Practices.ServiceLocation
Por ejemplo, cree una aplicación de consola y haga referencia solo a Microsoft.Practices.Unity (versión de archivo 2.0.414.0). Escriba el siguiente código y ejecutarlo:
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 {}
En mi máquina, la salida es:
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.
Ahora comentario la línea
LoadSchemaLoaders();
ejecutarlo de nuevo y funciona.
Esta es una versión simplificada del código de producción. El código de producción carga dinámicamente tipos personalizados que implementan una interfaz. Tan pronto como presentamos Unity, el código arrojó una excepción. ¡Pero los tipos de Unity no pueden implementar nuestra interfaz!
No entiendo cómo simplemente al reflexionar sobre el conjunto hace que el conjunto de Unity central requiera otra dependencia.
Exactamente correcto. Unity proporciona una implementación de IServiceLocator. Si no lo usa, no necesita el ensamblaje de localizador de servicio, pero cuando lo hace refleja la dependencia para obtener los metadatos de la interfaz. –
Gracias! Filtrando los ensambles con '.Where (x => x.FullName.StartsWith (" OurCompanyName. "))' Lo arregló. Es bueno saber por qué estaba sucediendo. – TrueWill
Ojalá pudiera volver a votar esto de nuevo - haber guardado mi tocino ... otra vez. No es la solución más elegante ... pero es lo suficientemente elegante. –