The issue of dependencies when initiating a new view model can be handled with IOC.
public class MyCustomViewModel{
private readonly IShoppingCartWebService _cartService;
private readonly ITimeService _timeService;
public ProductDTO ProductDTO { get; set; }
public ProductDetailsViewModel(IShoppingCartWebService cartService, ITimeService timeService){
_cartService = cartService;
_timeService = timeService;
}
}
When setting up the container...
Container.Register<IShoppingCartWebService,ShoppingCartWebSerivce>().As.Singleton();
Container.Register<ITimeService,TimeService>().As.Singleton();
Container.Register<ProductDetailsViewModel>();
When you need your view model:
var viewmodel = Container.Resolve<ProductDetailsViewModel>();
viewmodel.ProductDTO = myProductDTO;
When utilizing a framework such as caliburn micro there is often some form of IOC container already present.
SomeCompositionView view = new SomeCompositionView();
ISomeCompositionViewModel viewModel = IoC.Get<ISomeCompositionViewModel>();
ViewModelBinder.Bind(viewModel, view, null);
In general, I would not place business logic in the view model layer. But the term "Business Logic" is misleading.
Eric Evans uses a model where business logic is divided into two categories
- Domain logic - Logic related to the actual problem domain you are solving
- Application logic - Logic related to the fact, that you are building an application
He mentions the example of an accounting application. Rules about accounts, posts, tax accounts, etc. are domain rules, rules pertaining to the domain of accounting. Logic about CSV import/export has nothing to do with the domain of accounting. These rules exists purely because we are building a software application. These are examples of application logic.
Domain rules should NEVER go into the view model layer. If you are following the MVVM pattern, then the domain rules go, without question, in the model layer.
Application rules, like CSV import/export, could go in the view model layer. But personally, I would prefer to separate that out into a separate application logic layer.
The View Model should be very simple. Looking up the data needed by the view in the corresponding model, updating the model when the view changes, listening to events in the model, and propagating those events to the view, allowing the view to be updated when the model is updated behind the scenes (if applicable).
Personally I would make sure that the view model layer contains only one type of logic, presentation logic.
Best Answer
WCF's data objects should ideally be light-weight data transfer objects only. I would only re-use WCF's data objects if:
That being said, I have never actually used WCF data objects as my Models. Usually I create Model objects separately, and my client-side data access layer converts the WCF data objects into Models for my application to use.
I usually use something Automapper for this, which will automatically map data from one class to another, providing the names and types are the same.