2010-01-15 28 views
5

Tôi đã đi qua hai cách khởi tạo Views và ViewModels trong WPF CAL MVVM.Cách chính xác để khởi tạo một mô hình và xem trong WPF CAL MVVM

1 - Dường như phổ biến hơn. Yêu cầu bạn giải quyết ViewModel để tự động giải quyết Chế độ xem. ViewModel chứa thông tin về View.

public interface IView 
    { 
     void SetModel(IViewModel model); 
    } 

    public interface IViewModel 
    { 
     IView View { get; } 
    } 

    public class View 
    { 
     public void SetModel(IViewModel model) 
     { 
      this.DataContext = model; 
     } 
    } 

    public class ViewModel 
    { 
     private IView view; 

     public ViewModel(IView view) 
     { 
      this.view = view; 
     } 

     public IView View { return this.view; } 
    } 

2 - Dường như dọn dẹp hơn và xóa Chế độ xem khỏi Chế độ xem. Yêu cầu bạn giải quyết Chế độ xem để tự động giải quyết ViewModel. Tiêm đồ vật vào trong tầm nhìn (Không chắc chắn nếu điều này là tốt hay không).

public interface IView 
    { 
    } 

    public interface IViewModel 
    { 
    } 

    public class View 
    { 
     private IViewModel model; 

     public View(IUnityContainer unityContainer) 
     { 
      this.model = unityContainer.Resolve<IViewModel>(); 
      this.DataContext = this.model; 
     } 
    } 

    public class ViewModel 
    { 
    } 

Phương pháp được chấp nhận để khởi tạo chế độ xem và mô hình là những ưu điểm và nhược điểm của từng phương pháp. Bạn có nên tiêm các đối tượng vào chế độ xem của mình không?

Trả lời

3

Cả hai đều hợp lệ, nhưng # 1 có xu hướng được kiểm chứng hơn (ít nhất làm cho bạn kiểm tra ngắn gọn hơn). Ưu điểm của # 2 là nó có xu hướng rõ ràng hơn và giúp bảo trì rõ ràng hơn một chút, đặc biệt là khi bạn có nhiều doanh thu, loại điều đó. Làm cho ít giải thích hơn (mặc dù đây không phải là một lý do để áp dụng nó, nó chỉ là một sự thật).

Sự khác biệt là # 1 được gọi là Dependency Injection# 2 được gọi là Vị trí dịch vụ. Chúng thường bị nhầm lẫn bởi vì cả hai đều sử dụng một số loại container IoC (mặc dù điều này không phải là trường hợp).

Đó là vấn đề ưu tiên cuối cùng, nhưng như tôi đã nói tôi nghĩ bạn sẽ tìm thấy # 1 dễ dàng hơn nhiều để kiểm tra ... bạn sẽ không phải liên quan đến giao diện IUnityContainer trong thử nghiệm/chế nhạo của bạn.

1

Tùy chọn 1 có vẻ đúng, cho chế độ xem tham chiếu đến chế độ xem.

Có mô hình chế độ xem có tham chiếu ngược lại chế độ xem có vẻ hơi cá đối với tôi. Điều đó trông giống một kiến ​​trúc kiểu mô hình-người xem-người trình bày. Nếu bạn có các mô hình xem tương tác với khung nhìn và cần tham chiếu đến chế độ xem để bạn có thể tốt hơn khi tách chế độ xem trong mô hình chế độ xem được sử dụng hoàn toàn cho dữ liệu và người trình bày tương tác phức tạp hơn.

Tùy chọn 2 trông không có vẻ gì cả. Thông qua một tham chiếu đến container ioc vào các lớp học là một mùi mã lớn trong cuốn sách của tôi. Các cuộc gọi đến một container IoC nên được giảm thiểu. Trong hầu hết các ứng dụng của tôi, tôi chỉ gọi vào thùng chứa khi bắt đầu chương trình để nối dây. Tạo đối tượng năng động hơn thường được thực hiện với các lớp nhà máy.

+0

The View sở hữu trong tùy chọn 1 đã được tìm thấy bởi tôi trong các ví dụ khác nhau nhưng tôi đồng ý rằng nó không nên ở đó. – anon

2

tôi thích để xác định mô hình điểm trong XAML và cung cấp một thuộc tính chỉ đọc để truy cập gõ:

<UserControl ...> 
    <UserControl.DataContext> 
     <local:MyViewModel/> 
    </UserControl.DataContext> 

    ... 

</UserControl> 

public partial class MyView : UserControl, IMyView 
{ 
    public MyViewModel ViewModel 
    { 
     get { return this.DataContext as MyViewModel; } 
    } 

    ... 
} 
+0

+1 cho thuộc tính chỉ đọc –

1

Sự cố với mã này là tùy chọn 2 đang nướng nhiều hơn mức cần thiết. Nó thực sự không cần và không nên có một tham chiếu đến container.

Phương án thay thế cho phép tùy chọn 2 có thể kiểm tra như tùy chọn 1, nhưng rõ ràng hơn về khái niệm trong đó ViewModel không bao giờ biết về Chế độ xem.

Điều này đặc biệt hữu ích nếu bạn muốn chỉ định bố cục của mình bằng cách sử dụng tệp xml thay vì sử dụng vùng lăng kính, cho phép bạn dễ dàng định cấu hình bố cục.

Alternative:

public interface IView 
{ 
} 

public interface IViewModel 
{ 
} 

public class View : IView 
{ 
    private IViewModel model; 

    public View(IViewModel m) 
    { 
     this.model = m; 
     this.DataContext = this.model; 
    } 
} 

public class ViewModel : IViewModel 
{ 
} 

và ở một nơi khác bạn có:

Container.RegisterType<IViewModel, ViewModel>(/* appropriate container config */); 
Container.RegisterType<IView, View>(/* appropriate container config */); 

và bạn có thể tạo ra một cái nhìn bất cứ nơi nào với:

Container.Resolve<IViewModel>(); 
+0

+1 cho độ phân giải loại ghi chú không phải là công việc của chế độ xem. Tôi cũng sử dụng cách tiếp cận này và yêu thích nó. – RMart

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