2010-11-17 43 views
6

Tôi đang phát triển một ứng dụng WPF bằng cách sử dụng mẫu MVVM. Tôi đang sử dụng thư viện MVVM Light và tôi cũng đang cố gắng sử dụng một injector phụ thuộc (tôi đang xem xét Ninject và Unity).MVVM: Giao tiếp giữa Model và ViewModels

Tôi đã đọc rất nhiều bài viết trên blog và tôi khá bối rối về cách "thích hợp" làm cho các lớp của tôi giao tiếp với nhau. Đặc biệt, tôi không biết khi nào nên sử dụng Dependency Injection và khi nào nên dựa vào mẫu hòa giải.

Cho phép xem xét ví dụ. Tôi có một ViewModel, cho phép gọi nó là DataViewModel, và lớp Data cung cấp một số loại dữ liệu. Làm cách nào tốt hơn để liên lạc giữa chúng:

A. Tiêm phụ thuộc vào DataViewModel bằng giao diện IData? Bằng cách này, dữ liệu sẽ không phải dựa vào Messenger, nhưng nó sẽ phải cung cấp một sự kiện nếu dữ liệu thay đổi và ViewModel sẽ phải đăng ký với nó.

B. Dựa vào mẫu hòa giải (được thực hiện trong MVVM Light dưới dạng Messenger) và gửi tin nhắn giữa Model và ViewModel? Bằng cách này nó sẽ không cần thiết để sử dụng Dependency Injection ở tất cả, bởi vì toàn bộ thông tin liên lạc sẽ được dựa trên thông điệp.

Hơn nữa, ViewModels của tôi có nên tiêm phụ thuộc vào các Chế độ xem khác hay không, hoặc tốt hơn là chỉ dựa vào Messenger? Nếu đầu tiên, nó sẽ là cần thiết để xác định một giao diện riêng biệt cho mỗi ViewModel? Tôi nghĩ rằng việc định nghĩa một giao diện cho mỗi máy ảo sẽ là một công việc bổ sung, nhưng có lẽ nó đáng giá.

Trả lời

4

Nói chung ViewModel chuyển đến Dịch vụ (như Prism gọi nó) để truy xuất dữ liệu cần thiết. Dịch vụ đó được đẩy tới ViewModel qua DI (Constructor Injection) mặc dù bạn có thể thực hiện điều này theo cách khác thông qua ServiceLocator.

Do đó, ViewModel của bạn sẽ giữ tham chiếu đến dịch vụ sẽ xóa dữ liệu của bạn. Dữ liệu có thể đến từ một tệp tin DB, XML, người biết ... sự trừu tượng là ở đó. Vì vậy, đối với trường hợp IData của bạn, tham chiếu đến loại đó sẽ xảy ra tại một số điểm trong ViewModel nhưng không phải theo bất kỳ cách nào từ DI. Nếu khung công tác IoC của bạn cho phép nó (Prism làm) bạn tạo ánh xạ của các kiểu giao diện cho các loại cụ thể và sau đó lấy các kiểu đó thông qua vùng chứa của bạn; như vậy là trường hợp với Unity.

Dưới đây là một ví dụ ngắn gọn ... Tập lệnh bị ràng buộc với Chế độ xem và ViewModel được đưa vào Chế độ xem. Lưu ý việc sử dụng IScriptService để lấy dữ liệu. Dữ liệu trở lại là tập hợp các loại IScript, tuy nhiên chúng tôi không bao giờ chính thức được tiêm vào ViewModel vì chúng tôi không quan tâm đến loại hình như một thực thể duy nhất mà chúng tôi quan tâm về loại trên quy mô lớn.

 public ScriptRepositoryViewModel(IUnityContainer container, IScriptService scriptService, IEventAggregator eventAggregator) 
     { 
      _container = container; 
      _scriptService = scriptService; 
      _eventAggregator = eventAggregator; 
     } 

     public ICollectionView Scripts 
     { 
      get 
      { 
       if (_view == null) 
       { 
        _view = CollectionViewSource.GetDefaultView(_scriptService.Scripts); 
        _view.Filter = Filter; 
       } 

       return _view; 
      } 
     } 

Khi bạn thực hiện theo dõi, trường hợp tương tự có thể có ở đó, Chế độ xem sẽ được tiêm qua DI (Constructor Injection) với ViewModel. Tôi sẽ không làm cho ViewModels khác phụ thuộc vào nhau, giữ cho họ bị cô lập. Nếu bạn bắt đầu thấy nhu cầu ghép nối hãy xem dữ liệu bạn đang cố gắng chia sẻ, thường thì dữ liệu đó cần được trừu tượng hóa hơn nữa và không được kết hợp với bất kỳ ViewModel nào.

+0

Bây giờ tôi nhận được nó ... nhưng tôi cần một thời gian để làm quen với tiêm phụ thuộc và dịch vụ :) Cảm ơn! – madbadger

1

Có nhiều hơn một giải pháp tốt cho vấn đề của bạn,

tôi đề nghị bạn sử dụng một số giao diện duy nhất trong các mô hình dữ liệu của bạn, đặt nó trong một lớp cơ sở, giao diện này sẽ cho phép đối tượng dữ liệu của bạn để giao tiếp với thế giới bên ngoài.

Đối với các kiểu xem không tiêm dữ liệu nhưng giao diện có thể truy xuất dữ liệu cho bạn, dữ liệu sẽ hiển thị các sự kiện mà vm có thể đăng ký với chúng sau khi nhận được chúng.

dữ liệu không nên biết ai giữ anh ta, xem mô hình biết loại dữ liệu anh ta nắm giữ nhưng tôi không khuyên bạn nên tiêm dữ liệu này do sự cố linh hoạt.

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