2012-04-06 8 views
5

Wir verweisen in der Regel nur auf Microsoft.Practices.Unity.dll in unseren Anwendungen. Wir verwenden nur grundlegende Fähigkeiten, und das funktioniert gut. In einer Anwendung bewirkt die Verwendung der Reflektion, dass Unity eine andere DLL benötigt.Das Nachdenken über Baugruppen führt dazu, dass Unity Microsoft.Practices.ServiceLocation benötigt

Zum Beispiel erstellen Sie eine Konsolenanwendung und nur als Referenz Microsoft.Practices.Unity (Dateiversion 2.0.414.0). Geben Sie den folgenden Code und führen Sie es:

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 {} 

Auf meinem Rechner ist die Ausgabe:

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.

Jetzt kommentieren Sie die Zeile

LoadSchemaLoaders(); 

Run es wieder und es funktioniert.

Dies ist eine vereinfachte Version des Produktionscodes. Der Produktionscode lädt tatsächlich benutzerdefinierte Typen dynamisch, die eine Schnittstelle implementieren. Sobald wir Unity eingeführt haben, hat der Code eine Ausnahme ausgelöst. Aber Unity-Typen können unsere Schnittstelle nicht implementieren!

Ich verstehe nicht, wie einfach das Reflektieren über die Assembly bewirkt, dass die Unity-Assembly eine andere Abhängigkeit benötigt.

Antwort

7

A-Typ in der Einheit der Baugruppe von einer Schnittstelle in Microsoft.Practices.ServiceLocation definiert (wahrscheinlich IServiceLocator).

Der Compiler benötigt keine Anwendung auf Referenz, die direkt dll ... aber über das System.Type Objekt reflektiert wird versuchen, die DLL von Unity verwiesen zu laden.

Der Grund dies geschieht nur, wenn Sie über die Versammlung reflektieren, weil die Einheit wahrscheinlich nicht die Art laden, die Microsoft.Practices.ServiceLocation unter normalen Umständen verweist.

Als Behelfslösung, könnten Sie Ihre Assembly.GetTypes() -Aufruf in einem try/catch-Block umschließen.

Alternativ, wenn Sie den Microsoft.Practices.ServiceLocation dll in einem Ort gebracht, wo Ihre Anwendung finden kann, das sollte auch das Problem beheben.

+3

Genau richtig. Unity stellt eine Implementierung von IServiceLocator bereit. Wenn Sie es nicht verwenden, benötigen Sie die Service-Locator-Assembly nicht. Wenn Sie jedoch die Reflektion durchführen, ruft sie die Abhängigkeit auf, um die Metadaten der Schnittstelle abzurufen. –

+1

Danke! Das Filtern der Assemblys mit '.Where (x => x.FullName.StartsWith (" OurCompanyName. "))' Hat es behoben. Gut zu wissen, warum es passierte. – TrueWill

+0

Ich wünschte, ich könnte das noch einmal verbessern - es hat meinen Speck gerettet ... wieder. Nicht die eleganteste Lösung .. aber es ist elegant genug. –

Verwandte Themen