Goran
Goran

Reputation: 6518

App.Config in MVVM architecture

Every application contains some settings that are configurable. These settings can more or less put into two categories:

  1. Appearance of application: example can be window location, window size, default options on views etc.
  2. Business rules: these settings will be used by business logic.

In architecture that I implemented, View has its own project (WPF) and ViewModel has its own project (class library). From the lofical standpoint, View should be responsible of loading / saving view related settings, and ViewModel should be responsible for loading / saving business settings.

View settings are easy to handle. Create needed properties in Settings (app.config), and its easy to you can easily load save them.

However, ViewModel cannot access app.config settings through the built-in mechanisms that are Available in View project.

First idea I had was to make some helper methods that will allow me to read / write settings in app.config from ViewModel. What is your opinion? Am I complicating stuff here, or this is acceptable way of handling applic\tion settings?

Upvotes: 5

Views: 3362

Answers (3)

satnhak
satnhak

Reputation: 9861

I've been very impressed with this library: https://www.nuget.org/packages/UserSettingsApplied/. It basically allows you to serialize whatever you want to the user's roaming app config without any effort. It seems well thought out and well tested. This allows the view model to easily persist settings in the app.config.

FYI it is totally OK for the View project to reference View Model. More than that it is pretty much mandatory, so your view can do all of its persistence through the view model layer.

Upvotes: 0

Katie
Katie

Reputation: 1538

Here's a cleaner option, if you would like to keep your assemblies separate and keep your ViewModels testable:

In your ViewModel project, add an interface which provides methods or properties for retrieving and saving business settings. Have your ViewModels accept this interface as a dependency in their constructors.

In your View project, add a class which implements this interface and talks with Settings eg,

namespace ViewModel
{
    public interface IBusinessSettingsStore
    {
        public string SomeSetting { get; set; }
        public int AnotherSetting { get; set; }
    }

    public class SomeViewModel
    {
        private IBusinessSettingsStore _businessSettings;

        public SomeViewModel(IBusinessSettingsStore businessSettings)
        {
            _businessSettings = businessSettings;
        }

        private void DoSomething()
        {
            Console.WriteLine(_businessSettings.SomeSetting);
            _businessSettings.AnotherSetting = 10;
        }
    }
}

namespace View
{
    public class BusinessSettingsStore : IBusinessSettingsStore
    {
        public string SomeSetting
        {
            get => Settings.Default.SomeSetting;
            set => Settings.Default.SomeSetting = value;
        }

        public int AnotherSetting
        {
            get => Settings.Default.AnotherSetting;
            set => Settings.Default.AnotherSetting = value;
        }
    }
}

Upvotes: 0

default.kramer
default.kramer

Reputation: 6103

There are three ways you could go here.

  1. Add a reference to System.Configuration.dll and have your ViewModel project use the ConfigurationManager normally.

  2. Have the ViewModel project ask for the configuration information it needs via constructors or other methods of Dependency Inversion, and have the View project pass it in.

  3. Put the ViewModels and Views in the main application project.

Personally, I would go for option 3 unless there is some reason they need to be in separate assemblies. If they need to be separate, then I would favor option 1 because it's simpler.

Upvotes: 4

Related Questions