mercredi 27 avril 2016

Inheritance dependency injection simplification

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://ift.tt/1t2yfbU.

Aucun commentaire:

Enregistrer un commentaire