2012-04-29 34 views
14

Tôi đang làm việc trên một ứng dụng WPF có kích thước trung bình (MVVM) nên được mở rộng và duy trì trong tương lai. Vì vậy, tôi quyết định sử dụng một container IoC (Unity trong trường hợp này) để giữ cho mọi thứ linh hoạt.Nơi đặt và cấu hình container IoC trong một ứng dụng WPF?

Tuy nhiên tôi không chắc chắn nơi để đặt và cấu hình Unity trong một ứng dụng WPF.

Tôi cho rằng vùng chứa nên có thể truy cập được trên toàn cầu, vì vậy có thể nên chuyển đến lớp Ứng dụng. Nhưng tôi có nên biến nó thành tài sản tĩnh không? Tôi có nên cấu hình nó trong trình xử lý sự kiện Application_Startup() không?

Ví dụ:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    public static UnityContainer MyUnityContainer; 


    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     // instantiate and configure Unity 
    } 
} 

Bằng cách này tôi sẽ có thể truy cập vào container từ bất cứ nơi nào trong ứng dụng thông qua thuộc tính tĩnh:

App.MyUnityContainer 

Tôi đoán đây là một cách để làm điều đó nhưng tôi tôi không chắc liệu có các phương pháp hay hơn cho vấn đề này hay không, đặc biệt đối với các ứng dụng WPF.

Trả lời

8

Hãy xem qua số Composition Root Pattern. Những gì bạn muốn làm là khởi tạo nó trong trình xử lý sự kiện khởi động của bạn và quên đi sự tồn tại của nó cho phần còn lại của ứng dụng.

Bạn đang cố gắng triển khai Service Locator Pattern, tùy theo số nhiều is an inferior solution cho sự cố này.

+0

Làm thế nào tôi có thể quên hoàn toàn sự tồn tại của nó? Bạn sẽ muốn giải quyết các phụ thuộc ở cấp cao nhất của biểu đồ phụ thuộc của bạn, phải không? Ý tôi là, ví dụ, một trình xử lý sự kiện nhấn nút được cho là lưu 'Customer' vào cơ sở dữ liệu, sử dụng' CustomerRepository'. Bạn sẽ không phải giải quyết 'CustomerRepository' để sử dụng nó, do đó cần chứa IoC một lần nữa? –

+1

@JoaoMilasch Cấp cao nhất? Chắc chắn rồi. Nhưng tại sao mức cao nhất lại là một cửa sổ chứ không phải là lớp Ứng dụng? Trong trường hợp của bạn, bạn có một cửa sổ yêu cầu một kho lưu trữ, có thể được tiêm thông qua Constructor Injection. Sau đó, bạn có thể giải quyết MainWindow trong sự kiện Khởi động của Ứng dụng đang gọi vùng chứa. –

+0

Aha!Bạn đã trả lời câu hỏi của tôi một cách gián tiếp và bây giờ tất cả đều có ý nghĩa. Tôi đã nghĩ rằng tôi cần phải cấu hình container trên lớp App nhưng Windows sẽ cần truy cập trực tiếp vào thùng chứa được cấu hình. Thay vào đó, nếu tôi làm những gì bạn đang đề xuất, đối tượng chứa sẽ chỉ cần tồn tại trong lớp Ứng dụng. Đúng nếu tôi sai, làm ơn! :) Cảm ơn! –

5

Hãy để tôi đăng những gì tôi đã kết luận và hy vọng nó sẽ giúp mọi người ra ngoài. Đúng nếu có điều gì sai! : P

tôi đoán chúng tôi muốn được nhìn vào một cái gì đó như thế này:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     UnityContainer myUnityContainer = new UnityContainer(); 
     //make sure your container is configured 
     myUnityContainer.RegisterType<ISomeDependency, SomeDependencyImplementation>(); 
     myUnityContainer.RegisterType<IMainWindow, MainWindow>(); 

     myUnityContainer.Resolve<IMainWindow>().Show(); 
    } 
} 

public partial class MainWindow : Window, IMainWindow 
{ 
    private ISomeDependency _someDependency; 

    public MainWindow(ISomeDependency someDependency) 
    { 
     _someDependency = someDependency; 
    } 
} 

Lưu ý không có globals hoặc độc thân, container sống sót càng lâu càng MainWindow làm và tất cả phụ thuộc đằng sau quan điểm này nhập thêm vào biểu đồ thành phần được giải quyết tự động miễn là vùng chứa biết về chúng.

+1

Tôi nghĩ bạn muốn RegisterType thay vì Register. –

+0

Cảm ơn bạn đã sửa @JacobBrewer –

+1

@JoaoMilasch thiếu một phần và (không rõ ràng đối với tôi) thùng chứa "được quảng cáo" như thế nào trong một cái chính, một cái gì đó tương tự như bạn có thể có trong asp.net MVC bằng "GlobalConfiguration.Configuration .DependencyResolver ". "Giải quyết" chỉ kiểm tra nếu tất cả các phụ thuộc trong vùng chứa có tham chiếu. – stenly

1

Theo phiên bản mới của hộp chứa Unity, chúng tôi cũng phải đăng ký phiên bản của riêng nó để có được nó trong các mô hình xem thông qua quá trình xây dựng.

App.xaml.cs file:

protected override void OnStartup(StartupEventArgs e) 
{ 
     var unityIoC = new UnityContainer(); 
     unityIoC.RegisterTypes(AllClasses.FromAssembliesInBasePath(), WithMappings.FromMatchingInterface, WithName.Default); 
     unityIoC.RegisterInstance(typeof(IUnityContainer), unityIoC); 
} 

lớp Xem Mẫu

[InjectionConstructor] 
public MyViewModel(IUnityContainer container) 
{ 
} 

Bây giờ chứa đoàn kết sẽ được cung cấp cho chúng tôi theo quan điểm mô hình và có thể được sử dụng để giải quyết.

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