Use Singleton for model OR where to inject model into viewmodel? - c#

Normally I'd just use a singleton pattern for the model class Logbook. However, I'm trying to move towards learning about DI and want to inject the model into my viewmodel. In addition, I'm planning on having different child windows that open for various function (choose which logbook entries to display, sort order, add a logbook entry, etc) that may or may not need access to the model. What are the pros and cons of using the singleton pattern vs DI with these constraints? In addition, is DI possible if a lot of my viewmodels need access to this model? Finally, where/how should I instantiate the view, viewmodel, and model to be able to inject?

When you're using dependency injection, the idea is to provide classes with a specific implementation of the dependency it needs, so when you're unit testing, you can provide a mock or stub implementation. This is known as loose coupling.
Singletons, meanwhile, are global state that you have no control over. If your class accesses a singleton, it's tightly coupled to the singleton. How do you mock a singleton? In general, you don't. You're stuck to it, and suddenly you have untestable code. Singletons are generally considered an anti-pattern for exactly this reason. (Aside: there are ways around that, but the basic design problem still exists)
Even worse, if something in your class mutates the state of the singleton, this can have side effects in other tests you're writing and make it very difficult to figure out why Test B passes when run alone, but fails if it's run after Test A.
My rule of thumb is Don't use singletons, ever.
Your specific question sounds a little bit fishy. Your viewmodel shouldn't need a model injected into it. It sounds like you want a class responsible for retrieving or otherwise constructing your model, and then you'd inject an implementation of that class into your viewmodel.

Related

Unit testing classes that instantiate other classes

I'm trying to write unit tests for a class that instantiates other classes within it, but am struggling with how to instantiate those classes in a testable way. I'm aware of dependency injection, but this is somewhat different as the instantiation doesn't happen in the constructor.
This question really isn't specific to MVVM and C#, but that's what my example will use. Note that I've simplified this and it will not compile as-is - the goal is to show a pattern.
class ItemListViewModel
{
ItemListViewModel(IService service)
{
this.service.ItemAdded += this.OnItemAdded;
}
List<IItemViewModel> Items { get; }
OnItemAdded(IItemModel addedItem)
{
var viewModel = new ItemViewModel(addedItem);
this.Items.Add(viewModel);
}
}
class ItemViewModel : IItemViewModel
{
ItemViewModel(IItem) {}
}
As can be seen above, there is an event from the model layer. The ViewModel listens to that event and, in response, adds a new child ViewModel. This fits with standard Object Oriented programming practices that I'm aware of, as well as the MVVM pattern, and feels like quite a clean implementation to me.
The problem comes when I want to unit test this ViewModel. While I can easily mock out the service using dependency injection, I'm unable to mock out items added through the event. This leads to my primary question: is it OK to write my unit tests depending on the real version of ItemViewModel, rather than a mock?
My gut feel: that isn't OK because I'm now inherently testing more than ItemListViewModel, particularly if ItemListViewModel calls any methods on any of the items internally. I should have ItemListViewModel depend on mock IItemViewModels during testing.
There's a few tactics I've considered for how to do this:
Have ItemListViewModel's owning class listen to the event and add mocked out items. This just moves the problem around, though, as now the owning class can't be fully mocked out.
Pass an ItemViewModel factory into ItemListViewModel and use that instead of new. This would definitely work for mocking as it moves things to be based on dependency injection...but does that mean I need a factory for every class I ever want to mock in my app? This feels wrong, and would be a pain to maintain.
Refactor my model and how it communicates with the ViewModel. Perhaps the eventing pattern I'm using isn't good for testing; though I don't see how I would get around needing to ultimately construct an ItemViewModel somewhere in code that needs to be tested.
Additionally, I've searched online and looked through the book Clean Code, but this really hasn't been covered. Everything talks about dependency injection, which doesn't clearly solve this.
is it OK to write my unit tests depending on the real version of
ItemViewModel, rather than a mock?
Yes!
You should use real implementation as long as tests become slow or very very complicated to setup.
Notice that tests should be isolated, but isolated from other tests not from other dependencies of unit under the test.
Main issue of the testing is that applications using shared state (database, filesystem). Shared state makes our tests dependent on each other (tests for adding and removing items can not be run in parallel). By introducing mocking we eliminate shared state between tests.
Sometimes application being divided into independent domain modules, which "communicate" with each other via abstracted interface. To keep modules independent we will mock communication interface, so module under the test will not depend on implementation details of another domain module.
Mocking literally all dependencies will make maintenance/refactoring changes a nightmare, because every time you going to extract some logic into dedicated class you will be forced to change/rewrite test suit of the unit you are refactoring.
Your scenario is good example, by not mocking creating of ItemViewModel, you will be able to introduce a factory inject it into the class under the test and run already existing test suit to make sure that factory didn't introduce any regressions.
While I can easily mock out the service using dependency injection, I'm unable to mock out items added through the event.
Misko Hevery wrote about this pattern: How to Think About the New Operator
If you mix application logic with graph construction (the new operator) unit-testing becomes impossible for anything but the leaf nodes in your application.
So if we were to look at your problem code:
OnItemAdded(IItemModel addedItem)
{
var viewModel = new ItemViewModel(addedItem);
this.Items.Add(viewModel);
}
then one change we could consider is replacing this direct call to ItemViewModel::new with a more indirect approach
var viewModel = factory.itemViewModel(addedItem);
Where factory provides a capability to create ItemViewModel, and the design allows us to provide substitutes.
ItemListViewModel(IService service, Factory factory)
{
this.service.ItemAdded += this.OnItemAdded;
this.factory = factory;
}
Having done that, you can (when appropriate) use a Factory that provides some simpler implementation of your item view model.
When is this important? One thing to notice is that you are asking about ItemViewModel, but you aren't asking about List. Why is that?
A couple of answers: List is stable; we aren't at all worried that the behavior of List itself is going to change in a way that causes an observable change to the behavior of ItemListViewModel. If the test reports a problem later, there isn't going to be any doubt that we introduced a mistake in our code.
Also, this.List is (presumably) isolated. We don't have to worry that our test results are going to be flaky because some other code is running at the same time. In other words, are test is not vulnerable to problems caused by shared mutable state.
If those properties also hold for ItemViewModel, then adding a bunch of ceremony to your code to create separation between these two implementations isn't actually going to make your design any "better".

MVVM with Unity and Unit Testing architectural design

I'm building a Visual Studio-like application in WPF and I'm having some problems identifying the best architectural design organization of my components. I plan to use Unity as my dependency-injection container and Visual Studio Unit Testing framework and probably moq for mocking library.
I'll first describe the structure of my solution, then my questions:
I have a WPF project that contains:
My Unity container initialization (bootstrapper) on application startup (in App.xaml.cs)
All my application Views (XAML).
Another project called ViewModel this contains:
All my application ViewModels. All my ViewModels inherit from a ViewModelBase which exposes a ILogger property
My initialization logic is as follows:
Application Startup
Unity container creation and registration of types: MainView and MainViewModel
Resolve my MainView and show it.
var window = Container.Resolve<MainView>();
window.Show();
My MainView constructor receives a MainViewModel object in its constructor:
public MainView(MainViewModel _mvm)
My MainViewModel has a Child ViewModel for each of its panels:
public ToolboxViewModel ToolboxVM{get; set;}
public SolutionExplorerViewModel SolutionExplorerVM { get; set; }
public PropertiesViewModel PropertiesVM { get; set; }
public MessagesViewModel MessagesVM { get; set; }
And I'm planning to create a InitializePanels() method that initializes each of the panels.
Now here my questions:
How can my MainViewModel.InitializePanels() initialize all those panels? given the following options:
Option 1: Initialize the ViewModels manually:
ToolboxVM = new ToolboxViewModel();
//Same for the rest of VM...
Cons:
I'm not using the Unity container so my dependencies (e.g. ILogger) are not automatically resolved
Option 2: Use setter injection by annotating my properties:
[Dependency]
public ToolboxViewModel ToolboxVM{get; set;}
//... Same for rest of Panel VM's
Cons:
I've read that Unity Setter dependencies should be avoided since they generate a dependency with Unity in this case
I've also read that you should avoid using Unity for Unit Tests, so how to make this dependency clear in my Unit Tests? Having many dependent properties could be a nightmare to configure.
Option 3: Use Unity Constructor injection to pass ALL my Panel ViewModels to the MainViewModel constructor so they are automatically resolved by Unity container:
public MainViewModel(ToolboxViewModel _tbvm, SolutionExploerViewModel _sevm,....)
Pros:
The dependency would be evident and clear at time of creation, which could help building my ViewModel UnitTests.
Cons:
Having so many constructor parameters could get ugly pretty quickly
Option 4: Registering all my VM types at container buildup. Then passing the UnityContainer instance through constructor injection to my MainViewModel:
public MainViewModel(IUnityContainer _container)
That way I could do something like:
Toolbox = _container.Resolve<ToolboxViewModel>();
SolutionExplorer = _container.Resolve<SolutionExplorerViewModel>();
Properties = _container.Resolve<PropertiesViewModel>();
Messages = _container.Resolve<MessagesViewModel>();
Cons:
If I decide NOT to use Unity for my UnitTests, as many people suggest,then I won't be able to resolve and initialize my Panel ViewModels.
Given that lengthy explanation, what is the best approach so that I can take advantage of a Dependency Injection Container and end up with a Unit-Testable solution??
Thanks in advance,
First things first... As you noticed, your current setup might be problematic when unit testing (complex VM initialization). However, simply following DI principle, depend on abstractions, not on concretions, makes this problem go away immediately. If your view models would implement interfaces and dependencies would be realized through interfaces, any complex initialization becomes irrelevant as in test you'll simply use mocks.
Next, problem with annotated properties is that you create high coupling between your view model and Unity (this is why it is most likely wrong). Ideally, registrations should be handled at single, top level point (which is bootstrapper in your case), so container is not bound in any ways to object it provides. Your options #3 and #4 are most common solutions for this problem, with few notes:
to #3: too many constructor dependencies is usually mitigated by grouping common functionality in facade classes (however 4 is not that many after all). Usually, properly designed code doesn't have this problem. Note that depending on what your MainViewModel does maybe all you need is dependency to list of child view models, not concrete ones.
to #4: you shouldn't use IoC container in unit tests. You simple create your MainViewModel (via ctor) manually and inject mocks by hand.
I'd like to address one more point. Consider what happens when your project grows. Packing all view models into single project might not be good idea. Each view model will have its own (often unrelated to others) dependencies, and all this stuff will have to sit together. This might quickly become difficult to maintain. Instead, think whether you can extract some common functionalities (for example messaging, tools) and have them in separate groups of projects (again, split into M-VM-V projects).
Also, it's much easier to swap views when you have functionality related grouping. If project structure looks like this:
> MyApp.Users
> MyApp.Users.ViewModels
> MyApp.Users.Views
> ...
Trying out different view for user edit window is a matter of recompiling and swapping single assembly (User.Views). With all in one bag approach, you'll have to rebuild much larger part of application, even tho majority of it haven't changed at all.
Edit: keep in mind that changing existing structure of project (even tiny one), is usually a very costly process with minor/none business results. You might not be allowed or simply not be able to afford doing so. Usage-based (DAL, BLL, BO, etc) structure does work, it just gets heavier with time. You can just as well use mixed mode, with core functionalities grouped by their usage and simply adding new functionalities utilizing modular approach.
First off, you'd probably want to use interfaces rather than concrete classes, so that you'll be able to pass you mock objects when unit testing, i.e IToolboxViewModel instead of ToolboxViewModel, etc.
That being said, I would recommend the third option - constructor injection. This makes the most sense, since otherwise you could call var mainVM = new MainViewModel() and end up with a non-functional view model. By doing that, you're also making it very easy to understand what are your view-model's dependencies, which makes it easier to write unit tests.
I would check out this link, as it's relevant to your question.
I agree with Lester's points but wanted to add a few other options and opinions.
Where you are passing the ViewModel to the View through the constructor, this is a bit unconventional as WPF's binding capability allows you to completely decouple the ViewModel from the View by binding to the DataContext object. In the design you've outlined, the View is coupled to a concrete implementation and limits reuse.
While a service facade will simplify option 3, it is not uncommon (as you've outlined) for top-level ViewModels to have a lot of responsibilities. Another pattern you can consider is a controller or factory pattern that assembles the viewmodel. The factory can be be backed by the container to do the work but the container is abstracted away from the caller. A key goal in building container-driven apps is to limit the number of classes that understand how the system is assembled.
Another concern is the amount of responsibilities and object relationships that belong to the top-level viewmodel. If you look at Prism (a good candidate with WPF + Unity) it introduces the concept of "regions" that are populated by modules. A region may represent a toolbar which is populated by mutliple modules. Under such a design, the top-level viewmodel has fewer responsibilities (and dependencies!) and each module contains Unit-testable DI components. Big shift in thinking from the example you've provided.
Regarding option 4, where the container is passed in through the constructor is technically dependency inversion but it's in the form of service location instead of dependency injection. Having gone down this path before I can tell you it's a very slippery slope (more like a cliff): Dependencies are hidden inside classes and your code becomes a web of "just in time" madness -- completely unpredictable, totally untestable.

Busy constructors in Ioc - are they a code smell?

I have ended up with a constructor that looks like this whilst attempting to end up with an object i can easily test.
public UserProvider(
IFactory<IContainer> containerFactory,
IRepositoryFactory<IUserRepository> userRepositoryFactory,
IFactory<IRoleProvider> roleProviderFactory,
IFactory<IAuthenticationProvider> authenticationProviderFactory,
IFactory<IEmailAdapter> emailAdapterFactory,
IFactory<IGuidAdapter> guidAdapterFactory,
IRepositoryFactory<IVehicleRepository> vehicleRepositoryFactory,
IRepositoryFactory<IUserVehicleRepository> userVehicleRepositoryFactory,
IFactory<IDateTimeAdapter> dateTimeAdapterFactory)
This is all the dependencies the object will have and is the busiest constructor i have. But if someone saw this would it really raise a big wtf?
My aim was to end up with logic that is easy to test. Whilst it requires a good amount of mocks it is certainly very easy to verify my logic. However i am concerned that I may of ended up with too much of a good thing.
I am curious if this is normal for most people implementing ioc.
There are several simplifications I can make - such as I don't really need to pass in the factories for several of the adapters as i could just pass the adapter in directly as it has no internal state. But I am really asking in terms of the number of parameters.
Or more to the point i am looking for assurance that I am not going overboard ;)
But I am beginnign to get the impression that the UserProvider class should be broken down a bit - but then I end up with even more plumbing which is what is driving this concern.
I guess a sub question is maybe should I be considering using a service Locator pattern if I have these concerns?
When using DI and constructor injection violation of the SRP becomes very visible. This is acutally a good thing, and it is not DI / IOC's fault. If you were not using constructor injection, the class would have the same dependencies, it would just not be as visible.
What you could do in your concrete example is hide some of the related dependencies behind facades. For example IVehicleRepository and IUserVehicleRepository could be hidden behind an IVehicle facade. It might also make sense to put IUserRepository, IRoleProvider and IAuthenticationProvider behind a facade.
In my opinion that is a lot of parameters for a constructor. Here's how I would handle this to get good testability and reduce "code smell."
Instead of passing in the factories to create instances of your classes just pass in the classes themselves. This automatically cuts your dependencies in half because the UserProvider would not be concerned with creating any objects that it needs (and subsequently disposing of them if necessary) it would just use what is given to it instead of using the factories that it needs to create object instances that it needs.
Remove your adapters from the constructor and just create instances of these interfaces inside of the UserProvider. Think about how often are you going to need to change the way you format a guid for example. This would still be testable as long as your adapters don't have a lot of dependencies.
The point I'm making is to get a good balance of testability and practicality. When implementing Ioc try and determine where you've had trouble with testability in the past and where you've had issues maintaining and changing code because there were too many dependencies. That is where you'll see the most benefit.

Question on DI and how to solve some problems

I'm a newbie to Dependency Injection. I have never used and never even undestood what it is exatcly all about, but after my last attack on this topic I found out that is a way of uncoupling an object and its dependencies, once they are not responsible for instantiating the concrete versions of its dependencies anymore, as now the container will do it for us and deliver the ready object in our hands.
Now the point is; "when should I use it?", ALWAYS??? Actually, as I'm a newbie and have never even seen a project that uses this pattern I can't undestand how I should apply it to my domain objects!!! It seems to me that I will nevermore instantiate my objects and the container will always do it for me, but then comes some doubts...
1) What about oobjects that part of its dependencies comes from the UI, for example;
public class User(String name, IValidator validator)
Say that I get the user name from the UI, so how will the conatiner know it and still delliver this object for me?
2) Theres other situation I'm facing; if a dependency is now an object that is already instantiated, say... a SINGLETON object, for example . I saw theres settings regarding out the scope of life of the dependency beign injected (im talking about Spring.NET, eg; http request scope)... BUT, request and other web related things are on my presentation layer, so how could I link both my presentation layer and my domain layer without breaking any design rule (as my domain should be totally unaware of where its is being consumed, not to have layer dependency, etc)
Im eager to hear from you all. Thanks very much.
In general, once you go IoC, you tend to want to register EVERYTHING with IoC and have the container spit out fully-hydrated objects. However, you bring up some valid points.
Perhaps a definition of "dependency" is in order; at its broadest, a dependency is simply a set of functionality (interface) that a given class requires a concrete implementation of in order for the class to work correctly. Thus, most non-trivial programs are full of dependencies. To promote ease of maintenance, loose coupling of all dependencies is generally preferred. However, even when loosely coupled, you don't need to automate instantiation of dependencies if those objects require specialized information that you don't want to pollute your IoC registry with. The goal is to loosely couple usage, not necessarily creation.
Concerning point 1, some IoC frameworks don't do well with being given external parameters. However, you can usually register a delegate as a factory method. That delegate may belong to an object like a Controller that is given external information by the UI. Logins are a perfect example: Create an object, say a LoginController, and register it with IoC as your ILoginController. You'll reference that controller on your Login page, it will be injected when the Login page is instantiated, and the login page will pass it the credentials entered. The Controller will then perform authentication, and will have a method GetAuthenticatedUser() that produces a User object. You can register this method with IoC as a Factory for Users, and whenever a User is needed, the factory delegate will either be evaluated, or passed wholesale to the dependent method which will call it when it really needs the User.
On point 2, setting up a single instance of an object is a strength of the IoC pattern. Instead of creating a true singleton, with a private instance constructor, static instance and static constructor to produce an instance, you simply register the class with IoC and tell it to only instantiate it once and use that one instance for all requests. The strength is the flexibility; if you later want there to be more than one instance, you just change the registration. You won't break any design pattern rules either way; the view will always have a Controller injected, whether that Controller is the same for all pages or a new instance per request.
1) this contructor is probably not the right one to use, may be you are injecting the validator in the wrong place/way.
2)Neighter View nor Model and nor Controller should be aware of there is an IoC, it should lie in the background architecture ( where MVC components are actually instantiated )
You should use IoC when you feel the architecture can became complex and has to be mantained by many people. If you are writing an enterprise application, or a UI you think to extend with plugins, you probably need it, if you are writing a command line utility, probably not.
You should use dependency injection whenever you want any of the following benefits:
The ability to replace modules easily
The ability to reuse modules between parts of the application, or different applications
When you want to do parallel development, so that components of a system can be developed in isolation and in parallel because they depend on abstractions
When you want easier maintenance of a system because of loose coupling
When you want testability (a specialisation of replacing modules). This is one of the biggest reasons for using DI
To answer your other questions:
1) You can configure many IoC containers so that certain constructor parameters can be specified, whilst others are resolved by the container. However, you may need to think about refactoring that piece of code, as a UserFactory may be more appropriate which takes the validator dependency, and has a NewUser method which takes a user name and returns a new user (either instantiating it directly or resolving from the container).
2) Each application you build will have a composition root, where your container is configured, and the root object is resolved. Each app will therefore have its own IoC configuration, so there is an expected link between the application type and the configuration settings. Any common abstraction registrations can be placed in configuration code which can be shared amongst all applications.

Pattern for objects initialization at startup

I'm building an application and as time goes on, I have more and more objects to initialize at startup. Moveover, some of the newer objects depend on others so I'm getting some kind of spaggetti initialization where objects are created then passed to other constructors. I'm suspecting that I'm getting it wrong.
For example I have a WinForm which accepts a "Controller" class and 2 events. The controller needs to be told about the existence of a DataGridView from the WinForm so it has a method
Controller::SetDataGridReference(DataGridView^ dgv)
Is there a general method of instanciating objects at startup then referencing those objects to each another?
I've been told that putting all the required classes as constructor parameters is a good practice but frankly, I don't see how I can do that here.
I don't really think that the language matters
This looks like a textbook case for using dependency injection (DI). It will certainly help with your spaghetti code and can even assist with unit testing. If you want to make a gradual migration towards DI you might want to consider refactoring the objects with similar relationships and using a few sets of factory classes that can handle all the boilerplate chain intialization as well as centralizing where all that takes place in your code base.
I can recommend Google Guice as a good DI framework for Java. Even if you arent using Java it is a good DI model to compare against other language's DI frameworks
Two patterns pop into mind as possibly appropriate depending on the specifics of your problem:
Abstract Factory Pattern. This can work with or without the Dependency Injection approach suggested by #Scanningcrew.
Mediator Pattern. Construct a mediator. Pass the mediator into the constructor of each object. Have each object register with the mediator. Then the objects don't need to know about each other explicitly. This works well when you have a set number of objects interacting with each other.
Use the Controller Design Pattern.
That is, create a SINGLE class that will be instanced on program initialization, called Controller. On the constructor of that class, create all other objects. Whatever object that needs any other objects should receive said object as a parameter on its constructor. No one, no absolutely any other object should create anything on their constructor. Pass everything as parameters on their constructors. Also, on the Controller class destructor/dispose call all objects destructor/dispose method in reverse order. This won't reduce your code, but it will make if far better to understand and debug later on.
Dependency Injection should help here: at application boot you can choice to build the complete (or sort of) graph of objects. The entry point of your application will instantiate the DI container of your choice, the you just request the root object.
For example Google Guice comes with a very nice Object grapher.
For the objects interaction, I would go for a Mediator. Check out this definition:
"Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently."
For the instantiation, I would consider the Dependency Injection. Remember that you can freely use and mix design patterns to achieve your goals.

Categories

Resources