2012-04-06 6 views
5

일반적으로 Microsoft 응용 프로그램에서는 Microsoft.Practices.Unity.dll 만 참조합니다. 우리는 기본 기능만을 사용하고 있으며 이는 정상적으로 작동합니다. 한 응용 프로그램에서 리플렉션을 사용하면 Unity가 다른 DLL을 요구하게됩니다.어셈블리를 반영하면 Unity에서 Microsoft.Practices.ServiceLocation이 필요합니다.

예를 들어 콘솔 앱을 만들고 Microsoft.Practices.Unity (파일 버전 2.0.414.0) 만 참조하십시오. 다음 코드를 입력하고 실행 : 내 컴퓨터에

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

을, 출력은 다음과 같습니다

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.

지금 다시 라인을

LoadSchemaLoaders(); 

실행을 주석하고 그것을 작동합니다.

이것은 생산 코드의 단순화 된 버전입니다. 프로덕션 코드는 실제로 인터페이스를 구현하는 사용자 정의 유형을 동적으로로드합니다. Unity를 도입하자마자 코드가 예외를 던졌습니다. 그러나 Unity 유형은 우리 인터페이스를 구현할 수 없습니다!

어셈블리에 반영하여 코어 Unity 어셈블리가 다른 종속성을 필요로하는 것이 얼마나 쉬운 것인지 이해할 수 없습니다.

답변

7

Microsoft.Practices.ServiceLocation (아마도 IServiceLocator)에 정의 된 인터페이스에서 Unity 어셈블리의 형식입니다.

컴파일러에서는 응용 프로그램에서 해당 dll을 직접 참조 할 필요가 없지만 System.Type 개체를 통해 반영하면 Unity에서 참조하는 dll을로드하려고 시도합니다.

일반적인 상황에서 Unity가 Microsoft.Practices.ServiceLocation을 참조하는 형식을로드하지 않았기 때문에이 문제가 어셈블리에 반영 될 때만 발생합니다.

해결 방법으로 Assembly.GetTypes() 호출을 try/catch 블록으로 묶을 수 있습니다.

또는 Microsoft.Practices.ServiceLocation dll을 응용 프로그램에서 찾을 수있는 위치에두면 문제도 해결됩니다.

+3

정확하게 맞습니다. Unity는 IServiceLocator의 구현을 제공합니다. 사용하지 않으면 서비스 로케이터 어셈블리가 필요하지 않지만 리플렉션을 수행하면 인터페이스의 메타 데이터를 가져 오는 종속성이 발생합니다. –

+1

감사합니다. '.Where (x => x.FullName.StartsWith ("OurCompanyName."))'을 사용하여 어셈블리를 필터링했습니다. 왜 그런 일이 일어 났는지 알고 있습니다. – TrueWill

+0

나는 다시 이것을 업 그레 이드 할 수 있었으면 좋겠다. 다시 베이컨을 구했다. 다시. 가장 우아한 솔루션은 아니지만 충분히 우아합니다. –

관련 문제