This project has moved. For the latest updates, please go here.

WAP Without MEF

Mar 16, 2014 at 5:44 AM
Hi,

I am new to WAF and I am having a hard time to use it without MEF. I was going through the samples supplied with WAF assemblies. I would like to initialize my child ViewModels without using MEF. Child ViewModel will be bound to child controls at run time (for supplying DataContext). I do not have any window at Presentation layer only User Controls. My child ViewModel and User control implements I<ChildViewName>View. Now I want to initialize all child ViewModels inside ShellViewModel (I have exposed all child ViewModel as properties of ShellViewModel). When you use MEF constructor of ViewModel would be automatically called passing View's object but as I am not using MEF, how I can pass object of my respective User controls while initializing respective child ViewModel.

For example how I can initialize this manually:
public EmployeeInfoViewModel(IEmployeeInfoView view)
            : base(view)
        {
            this.showEmployeeValuesCommand = new DelegateCommand(GetEmployeeValues);
        }
in the ShellViewModel constructor:
public ShellViewModel(IShellView view)
            : base(view)
        {
            EmployeeInfoViewModel = new EmployeeInfoViewModel(
        }
Coordinator
Mar 16, 2014 at 3:22 PM
If the ShellViewModel is responsible to create other ViewModels per code then it needs all necessary information to do this:
public ShellViewModel(IShellView view, IEmployeeInfoView employeeInfoView) : base(view)
{
    EmployeeInfoViewModel = new EmployeeInfoViewModel(employeeInfoView);
}
However, such code might get cumbersome in medium size or larger applications. I recommend the usage of the Dependency Injection or the Service Locator pattern.

See also: Introduction of the IoC container concept.
Mar 16, 2014 at 5:18 PM
Edited Mar 16, 2014 at 5:21 PM
As far as I understand in WAF we inject View to ViewModel. My problem is at the time of creation of ViewModel object (in this case ShellViewModel) I do not have any information about View that I can pass to respective ViewModel (parent or child). This happens automatically if you use MEF because MEF knows about where to find concrete implementation of a View (using Export and Import) so it create the object and pass it to ViewModel constructor. But here in my case I am creating first ViewModel (ShellViewModel) object in ModuleController which is in Application layer so no reference of Views which are in Presentation layer. So I think even above suggested approach will not work because ViewModel have no idea about View's concrete implementation class. How I resolve it. Does WAF provide any way to do it. Here is more elaborated code.

Application Layer
public interface IEmployeeInfoView : IView
    {

    }
    public class EmployeeInfoViewModel : ViewModel<IEmployeeInfoView>
    {
        private string name;
        
        private readonly DelegateCommand showEmployeeValuesCommand;

        public string Name
        {
            get { return name; }
            set { SetProperty(ref name, value); }
        }

        public ICommand ShowEmployeeValuesCommand { get { return showEmployeeValuesCommand; } }

        public EmployeeInfoViewModel(IEmployeeInfoView view)
            : base(view)
        {
            this.showEmployeeValuesCommand = new DelegateCommand(GetEmployeeValues);
        }

        private void GetEmployeeValues()
        {
        }
    }
public class ShellViewModel : ViewModel<IShellView>
    {
        private EmployeeInfoViewModel employeeInfoViewModel;

        public EmployeeInfoViewModel EmployeeInfoViewModel
        {
            get { return employeeInfoViewModel; }
            set { SetProperty(ref employeeInfoViewModel, value); }
        }

        public ShellViewModel(IShellView view)
            : base(view)
        {
            EmployeeInfoViewModel = new EmployeeInfoViewModel(IEmployeeInfoView);
        }

    }
Presentation Layer
public partial class EmployeeInfoControl : UserControl, IEmployeeInfoView
    {
        public EmployeeInfoControl()
        {
            InitializeComponent();
        }
    }
And finally ModuleController will initialize top level ViewModel (ShellViewModel) as a starting pointing. ShellViewModel will be a DataContext for Main User control. Main User control will have various child user controls responsible for various task as a unit. In the similar way ShellViewModel will contain child ViewModels providing data and logic to child user controls inside Main user control. So I will only kick start only ShellViewModel and it will initialize all child ViewModels. I used to do this approach in my last project where we have used MVVM Light. But there is not requirement of injecting views into ViewModel in MVVM Light.

This approach is essential because we host our WPF modules in a framework based on Windows Form and uses ElementHost to show WPF controls (by hosting Main User control from View assembly). So we do not have any WPF window, only user controls. These user control assembly supplied to a fore said framework. The framework will be responsible for calling ModuleController code where will initialize top level ViewModel. Earlier in MVVM Light we used to start this initialization using Main User control not the MainViewModel (or ShellViewModel) and Main user control was responsible to initialize MainViewModel and setting it as its own DataContext.

The main problem is we do not any reference of View layer into ViewModel and it should not be, right? So what you suggest?
Coordinator
Mar 20, 2014 at 7:25 PM
Who will be responsible to create the concrete View objects?

In the WAF sample applications I’m using MEF (Dependency Injection) to create the Views. But I still have to tell MEF where it will find the concrete View implementations. This is done in the App.xaml.cs class which resides in the Presentation layer.

I believe your framework should call a class in the Presentation layer because it is the only layer that is allowed to have dependencies to all other layers. This class will be responsible to create the concrete View objects and to create the ModuleController. How the concrete View objects are passed to the Controllers so that they can create the ViewModels is up to you. The Service Locator pattern would be a good approach.
Mar 22, 2014 at 7:32 AM
Hi,

Thanks for the replying. It seems in WAF there is no way to create ViewModel object without using a Dependency Injection technology like MEF or Unity. My point was asking above queries was if we can use WAF without using Dependency Injection means usual way to create objects but it seems not. As in other parts of the project we are using Unity so for sack of consistency I have used Unity in WAF as well. Now I able to create ViewModel objects by injecting View object using Unity. Thanks once again for you responses.