Moonshield
Moonshield

Reputation: 935

MVVM - injecting model into viewmodels vs. getting model via singleton

In my application the model is a dataset representing a database and thus at any point in the execution of the application there should only be one model object. Currently this is created when the application starts up and is stored as a property in the application class. The viewmodels receive a reference to the dataset/model via their constructors.

Seeing as there can only be one dataset, would it be better to implement a singleton class that will create/return the dataset and have the viewmodels get their reference from that (are there any problems with this approach)?

Thanks, James

Upvotes: 1

Views: 2580

Answers (2)

Falcon
Falcon

Reputation: 3160

From my personal experience, this is a rocksolid approach:

  1. You prevent instantiation of more than one instance of the Dataset
  2. You have it globally available, which is what you want and makes life easy

However, OOP-Zealots will argue that you should not use a classical Gang of Four Singleton (with the static Instance Property), but a DI Singleton, an Object that is created by the DI Container only once and then passed everywhere.

Personally, I think this is a tradeoff: The GoF Singleton is easy to use and simple. I've never had a case where I had to replace it or the database-access in general. I do have an interface for database access and if in need I could change the Implementation within the Singleton (and enhance it, so that it is possible even during runtime). It can also save you a lot of boilerplate code, but keep in mind that your model is then very tightly coupled to the database and can't exist without it.

The sole advantage of the DI stuff that I can see is that you can configure it from an external config as I doubt the lifecycle management of your database access will ever change, which would be the other advantage of DI. And your ObjectModel might be kept cleaner in the long run (plus for big projects).

I personally like to use this Generic Singleton Implementation. Some object fetishists would argue again it's more a wrapper than a singleton, but it's does a good job and even allows you to keep your ObjectModels ("as opposed to ViewModels", don't get that wrong) pure as you don't need to implement them as singletons with static members:

public class Singleton<T> where T : class {
    static object SyncRoot = new object( );
    static T instance;
    public static T Instance {
        get {
            if ( instance == null ) {
                lock ( SyncRoot ) {
                    if ( instance == null ) {
                        ConstructorInfo ci = typeof( T ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null );
                        if ( ci == null ) { throw new InvalidOperationException( "class must contain a private constructor" ); }
                        instance = (T)ci.Invoke( null );
                    }
                }
            }
            return instance;
        }
    }
}

http://www.sanity-free.com/132/generic_singleton_pattern_in_csharp.html

Upvotes: 4

Aliostad
Aliostad

Reputation: 81660

Having that on constructor will make it more flexible. In fact you can implement Singleton and pass the same singleton instance all the time or get the DI framework to keep it as a singleton if you are using one.

This will prevent your ViewModel to have knowledge of the lifetime of the model which makes unit testing easier.

One thing with Datasets though - they are not really a model since they are loose. Even if you have to use Dataset, I would have created entity class models and translated them. Dataset is not DDD.

Upvotes: 4

Related Questions