在WPF / MVVM应用程序中加载配置文件/启动时处理错误

Chr*_*cht 5 c# wpf error-handling configuration mvvm

免责声明:我没有MVVM / MVC / MVP / MV的经验,但是,这是我第一次尝试使用任何 UI分离模式。

启动时,我的应用程序需要从配置文件加载数据,该文件是应用程序正常运行所必需的。

目前,我正在启动中读取配置文件App.xaml.cs,并将该文件的内容传递给视图模型:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        string configFile = "settings.txt";
        string[] config = File.ReadAllLines(configFile);

        var window = new MainWindow();
        var viewmodel = new MainWindowViewModel(config);
        window.DataContext = viewmodel;
        window.Show();
    }
}
Run Code Online (Sandbox Code Playgroud)

1.这是“正确的” MVVM方法吗?
我敢肯定,这种方法比直接在视图模型中读取文件更好(这是我首先这样做的方法),但是我不确定是否App.xaml.cs完全适合读取配置文件。

2.我在哪里/如何处理错误?
配置文件中的数据对于应用程序至关重要。
因此,如果文件丢失或为空,或者文件中的数据无效,那么我需要显示一条错误消息并退出该应用程序。

我的第一个尝试就是将其放入App.xaml.cs

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        string configFile = "settings.txt";

        if (!File.Exists(configFile))
        {
            MessageBox.Show("config file missing");
            Application.Current.Shutdown();
            return;
        }

        string[] config = File.ReadAllLines(configFile);

        if (config.Count() == 0)
        {
            MessageBox.Show("config file empty");
            Application.Current.Shutdown();
            return;
        }

        var window = new MainWindow();
        var viewmodel = new MainWindowViewModel(config);
        window.DataContext = viewmodel;
        window.Show();
    }
}
Run Code Online (Sandbox Code Playgroud)

但这在我看来并不“正确”。我已经不满意将文件加载到那里(请参阅第一个示例),因此情况甚至更糟。

注意:我知道我可能不应该直接致电Messagebox.Show这里。
请注意,这不是我要问的-我知道我应该用更像MVVM的东西代替它,但是重点是:我仍然必须从某个地方调用它(然后关闭应用程序)。
我真正想知道的是是否App.xaml.cs合适的地方!

3.另外,我还有另一种错误要处理:
配置文件的实际解析是由模型完成的(模型是现有库的一部分,而我在此处构建的WPF应用程序只是一个不错的用户界面) )
因此,视图模型创建该模型的实例并调用解析方法...如果配置文件中的数据无效,则抛出异常。

如何以“ MVVM方式”处理此问题?
在视图模型中捕获异常并从那里关闭整个应用程序对我来说是错的。


编辑:

回答威尔对我为什么不使用的评论app.config

我使用的是“特殊”配置文件,因为我需要从那里加载值对的几个命名“集”。这是一个示例文件
基本上,这是一个Dictionary<string, List<ClassWithTwoStringProperties>>

  1. AFAIK app.config不支持这样的数据,所以我唯一能做的就是将整个内容另存为blob中的一个属性app.config,而自己仍然进行解析。
    ->因此,我仍然必须从WPF应用程序中的某个位置调用解析。
  2. 我想要一种简单的,可人工编辑的格式
  3. WPF应用程序只是一个很好的库用户界面,我也需要库中的配置文件

Den*_*nis 4

我认为,这种做法是错误的。

您应该考虑app.config任何持久数据(例如数据库、文件)。如果您想以 MVVM 方式访问持久数据,您应该编写一个服务(类似于IApplicationDataService)并从代码中调用此服务实现MainWindowViewModel。如果您从某些服务中找到此服务ServiceLocator或通过 IoC 容器注入它,这将更加 MVVMish - 这有助于稍后编写单元测试。

服务的实现应该返回到视图模型初始化的模型实例。像这样的东西:

public ApplicationDataService : IApplicationDataService
{
  public ApplicationModel LoadApplicationData()
  {
      // process app.config here
  } 
}

public ViewModelBase<TModel>
{
  public TModel Model
  {
    get { return model.Value; }
  }
  private readonly Lazy<TModel> model = new Lazy(GetModel);

  protected abstract TModel GetModel();
}

public MainWindowViewModel<ApplicationModel> : ViewModelBase
{
   protected override ApplicationModel GetModel()
   {
      try
      {
        var dataService = ServiceLocator.GetService<IApplicationDataService>();
        return dataService.LoadApplicationData();
      }
      catch (AnyException e)
      {
         // oops!
      }
   }
}
Run Code Online (Sandbox Code Playgroud)