Registering the Repository in the DI Container

Right, the magic of Dependency Injection containers. Let’s start small by registering our MockRepository against the IRepository<ToDoItem> interface, and using the DI container to retrieve it in our View.

I’m going to register the interface inside the App’s constructor. This is cross-platform, so it’s the constructor inside the .NET Standard library, not the platform-specific projects.

This tells my DI container to give me an instance of my MockRepository class every time I ask for an IRepository<ToDoItem>. Since that’s exactly what I need for my View, I can change that to:

as a First step. Go and set a breakpoint where you retrieve the repo from the DI container, and you’ll see that you get an instance of a MockRepository when you ask for an IRepository<ToDoItem>.

The most important thing here is that the View is now decoupled from the MockRepository, i.e. it doesn’t decide which concrete class should be used as a repository. That means that when, later on, we want to use a real repository instead of our mockup, we only have to change the registration in our App’s constructor, rather than having to hunt down every line where we’re creating a new instance of a class that takes an IRepository as a constructor argument.

That said, this can still be improved upon – more on that in the next post.

Handling Dependency Injection in the View

OK, after all that testing, let’s head back to the app itself, where we have introduced a bit of a problem when we changed the View Model to use Dependency Injection via the constructor.

Just to recap: Here is the current constructor for our ViewModel, where we’re injecting our repository (just the relevant bits):

… and here is our current View:

As it stands, the ViewModel is going to throw an ArgumentNullException, so we need to do something about that.

Now, the quick and dirty way to handle this would be to create the repository in the constructor for our View and inject it right there, but that violates the principles of MVVM big time. The View should have no knowledge of, well, pretty much anything except for the ViewModel (ideally).

Furthermore, creating an instance of the ViewModel creates tight coupling. In my opinion, since it’s between two classes that are very closely related, that might be acceptable. Still, loose coupling would be preferable.

A popular solution to this problem is to use a Dependency Injection Container, and, as luck would have it, there’s a very simple one, called SimpleIoc, baked into the MVVMLight package.

Again, there’s tons to read about DI containers, and I’d encourage you to do so. For now, let’s stick to the very basics: a DI container allows you to register a class for retrieval later, BUT it also does allow you to register a class against an interface and, by magic, will substitute those interfaces for the registered classes when found in a constructor.

Yes, that sounds complicated, but in practice it really isn’t. Over the next few posts I’m going to walk you through the process, step-by-step.

 

Handling Errors in the ViewModel

OK, this time round I’m going to look at what I want my ViewModel to do when things go wrong. If, for instance, the repository for my ToDoItems throws an exception.

Obviously I don’t want my app to crash if that happens, so I need to catch the possible exceptions and deal with them gracefully. In this instance I think I want to display an error message instead of my list of ToDoItems. What I’ll need for that is a) a label to display said error message and b) some way of toggling the visibility of my error message and list.

I can implement a) by simply adding a string property, and b) by binding the visibility of said elements to a boolean property in my ViewModel.

Now I only need to put my repository code in a try-catch block and handle exceptions:

Ok, right now I’m using a catch-all exception handler here, which is not great, but right now it’s all I need. I reserve the right to change my mind later.

In other news, I initialise my IsFaulted and ErrorMessage properties optimistically in my constructor, and only change them if things go horribly wrong while trying to get the data from the repository.

With that in place I can now add another test:

This time round I’m setting my repo mock up to throw an exception (asynchronously!) whenever the GetAsync method is called, and assert that my IsFaulted and ErrorMessage properties have the correct values.

…and now I think that’s enough testing for now. Time to go back to the app itself – in the next article!

Mocking Your Tests – Ha Ha!

Up until now we’ve been using a hand-rolled mock repository to supply data to our app and out unit tests. And while that’s a good first step, it gets clumsy very quickly when trying to cover different scenarios inside out unit tests. For instance, I want to write a test that asserts that the data from the repository is loaded correctly, but I also want to test that my ViewModel behaves correctly if the data retrieval from the repo fails for some reason.

Writing separate classes for each scenario is a tad over the top. fortunately there’s a simple solution: mocking frameworks. Mocking frameworks allow you to mock only the things you need for a test.

sounds a bit fuzzy, I know, so let me just show you how it works. the following code uses the Moq framework – there are others out there if you fancy. Anyway, here’s the code for my previous test, this time using Moq:

OK, let’s take a look at that. First off I’m creating a list of ToDoItems and populate it with a few dummy values. This is the list I want my mock repository to return when its GetAsync() method is called.

After that I create the mock for my IRepository<ToDoItem>. This will essentially have the same function as my MockRepository class before. Except that it’s a lot quicker to create, as you can see.

The following line is where the mocking magic happens. The Setup method of my repo mock takes an argument specifying which method to mock, followed by what that method call should return. Moq supports both synchronous and asynchronous methods now via Returns() and ReturnsAsync() respectively. In this case I’m setting the mock up to return the list of ToDoItems I created earlier whenever the GetAsync() method is called.

Finally I inject the mock for my IRepository<ToDoItem> into the constructor of my OverviewVM class. Note that I’m passing repoMock.Object, not just repoMock as a parameter. This is something that’ll likely catch you out the first few times. It certainly did with me.

After that the code remains the same. I call the LoadData method of my OverviewVM, which promptly returns the list I specified in the setup of my mock. Neat, huh?

…and in the same way we can now test how we want our OverviewVM to react if the repository fails to load the data for some reason. What that reactions should be – now that’s the topic of the next post…