MVVMLight ViewModelLocator

Feb 9, 2011 at 6:47 PM
Edited Feb 9, 2011 at 6:49 PM

Recently I started a project and wasn't really using MVVMLight VML, was just dropping the ViewModel onto the XAML. Decided to go back and run the locator for another reason.  So now I am faced with an issue related to the start of sterling.  From what I have seen if I declare the VML in the app.xaml it doesn't fire off the Sterling service start in the ApplicationLifeTimeObject.

This comes about in the LoadData in the Viewmodel, when it hits the DB Query line to pull in data from the files, it dies with a null reference to the Sterling instance, any suggestions?

I am using the lastest changeset.

Edit:  This is on the WP7 Emulator.

Coordinator
Feb 9, 2011 at 7:11 PM

Sounds like a major issue with MVVM Light if the application lifetime is being ignored. You can just as easily use a singleton pattern to do it if that is not working, but I'd be more concerned with the fact that it is not firing the registered lifetime object, as those should be independent of whatever else is there. You might want to log something to MVVM Light in order to find out.

This should work for you - I haven't tested the code but the gist is that you manage the life cycle, first time you access it, it spins it up for you and gives you a reference, then hooks into the application exit and disposes for you:

 

public class SterlingService 
{
     static SterlingService()
     {
         Current = new SterlingService();
     }

     public SterlingService() 
     {
         _engine = new SterlingEngine();
          if (Debugger.IsAttached)
        {
            _logger = new SterlingDefaultLogger(SterlingLogLevel.Verbose);
        }

        _engine.SterlingDatabase.RegisterSerializer<MySerializer>();

        _engine.Activate();
        Database = _engine.SterlingDatabase.RegisterDatabase<MyDatabase>();
        ((App)Application.Current).Exit += (o,e) => { Cleanup(); }
     }

    public void Cleanup()
    {
        if (Debugger.IsAttached && _logger != null)
        {
            _logger.Detach();
        }
        if (_engine != null)
        {
            _engine.Dispose();
        }
        _engine = null;
    }

}

Feb 9, 2011 at 9:33 PM

Jeremy,

thanks for the quick reply. I will give it a whirl and see what happens...

Feb 11, 2011 at 8:49 PM
Edited Feb 11, 2011 at 9:08 PM

I am having the same issue. What happens is the ViewModelLocator is actually instantiated BEFORE The Application_Launching event is fired. Question is.... what is the "proper" way to handle this? I'm new to SL, WP7 and MVVM so I'm admittedly a bit lost! I'm sure I could MAKE it work, but what would you recommend doing to correct this?

What I've done in the meantime is wrap the DB property with a null check that activates the db, like so --

        public static ISterlingDatabaseInstance Database
        {
            get
            {
                if (_database == null)
                    _ActivateEngine();
                return _database;
            }
        }

Then, I changed the ActivateEngine method to a static (so the property can access it) and add a check to ensure that the engine is only activated once --

        private static void _ActivateEngine()
        {
            if (_database == null)
            {
                _engine = new SterlingEngine();
                _logger = new SterlingDefaultLogger(SterlingLogLevel.Information);
                _engine.Activate();
                _database = _engine.SterlingDatabase.RegisterDatabase<PoolToolDatabase>();
            }
        }
Have I been a bad boy?

Coordinator
Feb 11, 2011 at 9:06 PM

Did you try the class above? Did that work or not for you?

Feb 11, 2011 at 9:11 PM

To be honest, I wasn't sure how that class would be wired in... I'm also didn't see anything for handling tombstoning in the example, so that scared me off too.

Coordinator
Feb 11, 2011 at 9:49 PM

The user's guide covers tombstoning and everything needed that should be independent of the view model locator: http://www.sterlingdatabase.com/

Feb 11, 2011 at 9:58 PM

Thanks. I appreciate the lightning quick responses, Jeremy! I've been to the users guide and read it about 10 times so far ;-).

I may be coming off sounding like an idiot simply because I'm in a little bit over my head in a new area. But I'm thinking the tombstoning uses the _ActivateEngine method. If I replace those hooks with this service code you suggest, how would I wire that back to the App Events so that tombstoning is still handled? Am I making sense or just talking crazy? Was my solution a bad idea?

Coordinator
Feb 12, 2011 at 12:52 AM

This page:

http://www.sterlingdatabase.com/sterling-user-guide/3-the-sterling-engine

Has an example at the bottom you can wire directly into your App.xaml code behind, and should work regardless of whether you are using a view model locator.