2011-02-10 38 views
11

Tôi có một hệ thống sử dụng MEF để tải các bộ phận. Mỗi bộ phận này dựa vào một thư viện cốt lõi. Khi tôi xây dựng dự án, tôi thêm một số phiên bản để các tập tin .dll như thế này:MEF Phụ thuộc và phiên bản

  • part1-1.0.0.0.dll
  • part2-1.0.0.0.dll

Ngoài ra, có một ứng dụng thực hiện thành phần MEF. Nó cũng sử dụng thư viện lõi. Tôi đã tìm thấy rằng tôi chỉ có thể triển khai các phần "dll", và thành phần hoạt động tốt vì ứng dụng đã tải thư viện lõi mà các bộ phận dựa vào. Vì vậy, hệ thống tập tin của tôi trông giống như sau:

  • /parts/part1-v1.dll
  • /parts/part2-v1.dll
  • nhà soạn nhạc-v1.exe
  • lõi-v1.exe

Sự cố tôi gặp phải là cách xử lý phiên bản lõi và bộ phận. Giả sử tôi thực hiện cập nhật cho lõi và một trong các phần. Sau đó, tôi triển khai các thay đổi. Vì vậy bây giờ hệ thống tập tin của tôi có thể trông giống như:

  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • nhà soạn nhạc -v1.exe
  • lõi-v1.dll
  • lõi-v2.dll

làm thế nào tôi có thể chắc chắn rằng part1-v1.dll sử dụng lõi-v1.dll, và part1-v2.d ll sử dụng core-v2.dll? Tôi cần tất cả các phiên bản của các phần được tải và sử dụng phiên bản lõi thích hợp.

Các lớp phần giống như thế này:

[Export(typeof(IPart))] 
public class Part1 
{ 
    public string GetSomethingFromCore() 
    { 
     return Core.GetSomethingFromCore(); 
    } 
} 

[Export(typeof(IPart))] 
public class Part2 
{ 
    public string GetSomethingFromCore() 
    { 
     return Core.GetSomethingFromCore(); 
    } 
} 

Trả lời

5

Không strong naming chăm sóc vấn đề của bạn? Nếu một assembly được xây dựng dựa trên một dependency có tên mạnh, thì bạn biết rằng nó sẽ chỉ chấp nhận chính xác cùng một dependency xuống byte cuối cùng.

Ngoài ra, nếu đặt tên mạnh quá hạn chế, bạn có thể đặt số phiên bản vào tên loại. Ví dụ:

[Export(typeof(IPart))] 
public class Part1v1 
{ 
    private readonly ICorev1 core; 

    [ImportingConstructor] 
    public Part1v1(ICorev1 core) 
    { 
     this.core = core; 
    } 
} 

[Export(typeof(IPart))] 
public class Part1v2 
{ 
    private readonly ICorev2 core; 

    [ImportingConstructor] 
    public Part1v2(ICorev2 core) 
    { 
     this.core = core; 
    } 
} 
+3

Tôi muốn quay lại phương pháp này. Lưu ý rằng Wim đã trừu tượng hóa chức năng 'Core' thành giao diện, điều này đặc biệt quan trọng bởi vì trong ví dụ của Lance, anh ta xuất hiện để tham chiếu 'Core' một cách tĩnh, Part1 và Part2 sẽ thực sự tham chiếu các trình đơn tĩnh khác, thường không phải là hành vi mong đợi. Bằng cách trừu tượng hóa chức năng cho giao diện, các đối số 'cốt lõi' thực sự có thể là singleton _instances_, cùng một đối tượng, xuất bản chức năng thông qua hai phiên bản giao diện khác nhau (ICorev1 và ICorev2). – Adam

+0

Hãy xem tất cả các hội đồng interop của Microsoft Office, và lưu ý cách chúng có v8, v9, v10 dll vv (với phiên bản trong không gian tên). Mỗi phiên bản mới _does_not_ xác định lại chức năng từ lần cuối cùng, nhưng chỉ đơn giản là _adds_ cho nó. Vì vậy, từ góc độ bảo trì, 'lõi' thực hiện của bạn sẽ (theo thời gian) giống như thế này (giả): nội bộ lớp cốt lõi: ICorev1, ICorev2 { ICorev1.GetSomethingFromCore() {} ICorev2.GetSomethingFromCore2 () {} } – Adam

1

Bạn cần phải cung cấp lắp ráp cốt lõi của bạn tất cả các bộ phận của bạn strong names, sau đó họ sẽ yêu cầu một kết hợp chính xác khi tải các hội đồng tham chiếu. Điều này cũng có nghĩa là bạn sẽ cần phải triển khai nhiều bản sao của hội đồng cốt lõi của bạn. I E. thay vì

  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • nhà soạn nhạc-v1.exe
  • lõi -v1.dll
  • lõi-v2.dll

Bạn sẽ có:

  • /parts/1-1/part1-v1.dll
  • /bộ phận/1-1/core-v1 .dll
  • /parts/1-2/part1-v2.dll
  • /parts/1-2/core-v2.dll
  • /parts/2-1/part2-v1.dll
  • /parts/2-1/core-v1.dll
  • nhà soạn nhạc-v1.exe
  • lõi-v1.dll
  • lõi-v2.dll

Con đường tôi đã làm điều đó trong quá khứ, chỉ để lưu trữ từng phần trong một thư mục riêng biệt cùng với tất cả các phụ thuộc mà nó cần. Ngay cả khi chúng (hiện tại) có cùng phiên bản như trong ứng dụng. Vì vậy, khi ứng dụng của bạn chuyển sang core-v2, tất cả các phần dựa trên lõi-v1 sẽ vẫn có nó.

Các vấn đề liên quan