2012-04-06 4 views
5

Chúng tôi thường chỉ tham khảo Microsoft.Practices.Unity.dll trong các ứng dụng của chúng tôi. Chúng tôi chỉ sử dụng các khả năng cơ bản và điều này hoạt động tốt. Trong một ứng dụng, hành động sử dụng sự phản chiếu gây ra Unity để yêu cầu một DLL khác.Phản ánh trên các assembly khiến Unity yêu cầu Microsoft.Practices.ServiceLocation

Ví dụ: tạo ứng dụng bảng điều khiển và chỉ tham khảo Microsoft.Practices.Unity (phiên bản tệp 2.0.414.0). Nhập đoạn mã sau và chạy nó:

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

Trên máy tính của tôi, đầu ra là:

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.

Bây giờ xóa bỏ dòng

LoadSchemaLoaders(); 

Run nó một lần nữa và nó hoạt động.

Đây là phiên bản mã sản xuất được đơn giản hóa. Mã sản xuất thực sự tự động tải các loại tùy chỉnh triển khai giao diện. Ngay sau khi chúng tôi giới thiệu Unity, mã đã ném một ngoại lệ. Nhưng các loại Unity không thể thực hiện giao diện của chúng tôi!

Tôi không hiểu làm thế nào chỉ đơn giản là phản ánh trên lắp ráp là gây ra lắp ráp Unity cốt lõi để yêu cầu phụ thuộc khác.

Trả lời

7

Loại trong hội đồng thống nhất từ ​​giao diện được xác định trong Microsoft.Practices.ServiceLocation (có thể là IServiceLocator).

Trình biên dịch không yêu cầu ứng dụng của bạn tham chiếu dll đó trực tiếp ... nhưng phản ánh đối tượng System.Type sẽ cố gắng tải tệp dll được Unity tham chiếu.

Lý do điều này chỉ xảy ra khi bạn phản ánh quá trình lắp ráp là vì Unity có thể không tải loại tham chiếu Microsoft.Practices.ServiceLocation trong các trường hợp bình thường.

Như một công việc xung quanh, bạn có thể kèm theo cuộc gọi Assembly.GetTypes() của bạn trong một khối try/catch.

Ngoài ra, nếu bạn đặt dll Microsoft.Practices.ServiceLocation ở vị trí mà ứng dụng của bạn có thể tìm thấy nó, điều đó cũng sẽ giải quyết vấn đề.

+3

Chính xác. Unity cung cấp việc triển khai IServiceLocator. Nếu bạn không sử dụng nó, bạn không cần lắp ráp dịch vụ định vị, nhưng khi bạn thực hiện việc phản ánh nó kéo trong sự phụ thuộc để có được siêu dữ liệu của giao diện. –

+1

Cảm ơn! Lọc các assembly với '.Where (x => x.FullName.StartsWith (" OurCompanyName. "))' Cố định nó. Tốt để biết tại sao nó xảy ra. – TrueWill

+0

Tôi ước tôi có thể upvote điều này một lần nữa - nó đã lưu bacon của tôi ... một lần nữa. Không phải là giải pháp thanh lịch nhất .. nhưng nó là đủ thanh lịch. –