1

This one is a bit complicated, so please read everything through. I'm working on some code that implements the MVVM Pattern for WPF. I have a XAML Markup extension that looks for a specific property on the datacontext. (It's a long and fun story, but out of scope) My view model will be set as the Dataconext on the view.

Here's an example of how I have implemented my BaseViewmodel...

public class ViewModelBase : IViewModelBase
{
    protected CommandManagerHelper _commandManagerHelper;

    //todo find a way of eliminating the need for this constructor
    public OrionViewModelBase(CommandManagerHelper commandManagerHelper)
    {
        _commandManagerHelper = commandManagerHelper;
    }

    private IExampleService _exampleService;

    public IExampleService ExampleService
    {
        get
        {
            if (_exampleService == null)
            {
                _exampleService = _commandManagerHelper.GetExampleService();
            }

            return _exampleService;
        }
    }
}

What's going on there is that I'm effectively lazy loading the _exampleService. I'm sure it's possible to use Lazy, but I've not got round to implementing that just yet.

My Xaml Markup will be looking for and making use of my the ExampleService it could also be used by code within the view model. It's going to be used all over the application.

A point to note is that my application will have only one instance of the ExampleServer that will be passed around, calling GetExampleService from anywhere in the application will return the same instance of the object. There will only be one instance of the ExampleService object, although it is not coded as a singleton.

Here is an example of how I am inheriting from my ViewModelBase...

internal class ReportingViewmodel : ViewModelBase
{
    private readonly IReportingRepository _reportingRepository;

    public ReportingViewmodel(CommandManagerHelper commandManagerHelper, IReportingRepository reportingRepository) : base(commandManagerHelper)
    {
        _reportingRepository = reportingRepository;
    }
}

This code works and works great. However, having to type ": base(commandManagerHelper)" every time that I implement a new inherited member of the ViewModelBase is prone to mistakes. I'm likely to have 100's of these implementations and each one needs to be right.

What I'm wondering is.... is there a way of implementing the same behaviour respecting the SOLID principles and not having to call the base constructor every time I implement an instance of the ViewModelBase?

i.e. I'd like the ReportingViewModel to look like this

internal class ReportingViewmodel : ViewModelBase
{
    private readonly IReportingRepository _reportingRepository;

    public ReportingViewmodel(IReportingRepository reportingRepository)
    {
        _reportingRepository = reportingRepository;
    }
}

but still have the ExampleService populated correctly.

I'm currently considering using the Service locator pattern for this, I'm also considering using a Singleton and I'm open to other better solutions.

The reason that I'm asking the question rather than diving in with code is that I know that the Singleton is generally an anti-pattern, to me it signifies that something else is wrong in the code. I've just read an article on IoC and it's slating the Service locator pattern here's the article http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container.

1 Answer 1

2

You can't get out of calling the base constructor. It doesn't really matter that IExampleService is only instantiated once and shared. Your ViewModelBase doesn't (and shouldn't) "know" that. All it needs to know is that whatever is injected implements that interface. That's one of the big benefits, because when you unit test classes you can inject a mocked version of that interface. If classes depended on a static reference to something buried within a base class then it wouldn't be possible to replace it with a mock for testing.

I use ReSharper. (Am I allowed to say that? I don't mean to advertise.) Among many other things it generates those base constructors for you. I'm sure at some point that's got to get built in to Visual Studio.

Sign up to request clarification or add additional context in comments.

3 Comments

I use ReSharper too. :D I'm looking for the best implementation of this solution.
I suppose there is another part to the problem. I have a view that uses my custom markup extension and has to have the views datacontext set even though the view doesn't really require a view model (It's a simple display dialog) The markup needs to know about the IExampleService, not the view. Is it still correct to create a whole viewmodel? Or is it ok have the markup pull the extension from elsewhere? (if it's ok means I can change the way the viewmodels are composed) Just need to figure out how to do it.
On reflection, I think the question about getting the markup extension to work without a viewmodel is another topic all together.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.