2012-04-06 25 views
5

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.

Respuesta

7

Un tipo en el ensamblaje de Unity desde una interfaz definida en Microsoft.Practices.ServiceLocation (probablemente IServiceLocator).

El compilador no requiere que su aplicación haga referencia directa a esa DLL ... pero al reflexionar sobre el objeto System.Type intentará cargar la DLL a la que hace referencia Unity.

La razón por la que esto solo ocurre cuando reflexiona sobre el ensamblado es porque Unity probablemente no cargue el tipo que hace referencia a Microsoft.Practices.ServiceLocation en circunstancias normales.

Como solución alternativa, puede adjuntar la llamada Assembly.GetTypes() en un bloque try/catch.

Alternativamente, si pone el dll de Microsoft.Practices.ServiceLocation en una ubicación donde su aplicación puede encontrarlo, eso debería resolver el problema también.

+3

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. –

+1

Gracias! Filtrando los ensambles con '.Where (x => x.FullName.StartsWith (" OurCompanyName. "))' Lo arregló. Es bueno saber por qué estaba sucediendo. – TrueWill

+0

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. –

Cuestiones relacionadas