diff --git a/App.xaml.cs b/App.xaml.cs index e19bbe8..4089151 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -1,10 +1,13 @@ -using System.Globalization; -using System.Linq; +using System; +using System.Globalization; +using System.IO; using System.Reflection; using System.Windows; using System.Windows.Markup; +using Newtonsoft.Json; using PettingZoo.Model; using PettingZoo.View; +using PettingZoo.ViewModel; using SimpleInjector; namespace PettingZoo @@ -26,16 +29,16 @@ namespace PettingZoo { var container = new Container(); + container.RegisterSingleton(() => new UserSettings(new AppDataSettingsSerializer("Settings.json"))); + container.Register(); container.Register(); - // Automatically register all Window and BaseViewModel descendants - foreach (var type in Assembly.GetExecutingAssembly().GetExportedTypes() - .Where(t => t.IsSubclassOf(typeof(Window)) || - t.IsSubclassOf(typeof(Infrastructure.BaseViewModel)))) - { - container.Register(type); - } + container.Register(); + container.Register(); + + // Note: don't run Verify! It'll create a MainWindow which will then become + // Application.Current.MainWindow and prevent the process from shutting down. return container; } @@ -48,5 +51,47 @@ namespace PettingZoo mainWindow.Show(); } + + + private class AppDataSettingsSerializer : IUserSettingsSerializer + { + private readonly string path; + private readonly string fullPath; + + + public AppDataSettingsSerializer(string filename) + { + var companyName = GetProductInfo().Company; + var productName = GetProductInfo().Product; + + path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + companyName, productName); + fullPath = Path.Combine(path, filename); + } + + + public void Read(UserSettings settings) + { + if (File.Exists(fullPath)) + JsonConvert.PopulateObject(File.ReadAllText(fullPath), settings); + } + + + public void Write(UserSettings settings) + { + Directory.CreateDirectory(path); + File.WriteAllText(fullPath, JsonConvert.SerializeObject(settings, Formatting.Indented)); + } + + + private T GetProductInfo() + { + var attributes = GetType().Assembly.GetCustomAttributes(typeof(T), true); + if (attributes.Length == 0) + throw new Exception("Missing product information in assembly"); + + return (T)attributes[0]; + } + } } } diff --git a/Model/ConnectionInfo.cs b/Model/ConnectionInfo.cs index 2e4ef77..8ba3ba4 100644 --- a/Model/ConnectionInfo.cs +++ b/Model/ConnectionInfo.cs @@ -10,19 +10,5 @@ public string Exchange { get; set; } public string RoutingKey { get; set; } - - - public static ConnectionInfo Default() - { - return new ConnectionInfo - { - Host = "localhost", - Port = 5672, - VirtualHost = "/", - Username = "guest", - Password = "guest", - RoutingKey = "#" - }; - } } } diff --git a/Model/RabbitMQClientConnection.cs b/Model/RabbitMQClientConnection.cs index 0b9c4b5..0cd573d 100644 --- a/Model/RabbitMQClientConnection.cs +++ b/Model/RabbitMQClientConnection.cs @@ -64,7 +64,7 @@ namespace PettingZoo.Model Password = connectionInfo.Password }; - var statusContext = String.Format(@"{0}:{1}{2}", connectionInfo.Host, connectionInfo.Port, connectionInfo.VirtualHost); + var statusContext = String.Format("{0}:{1}{2}", connectionInfo.Host, connectionInfo.Port, connectionInfo.VirtualHost); while (!cancellationToken.IsCancellationRequested) { diff --git a/Model/UserSettings.cs b/Model/UserSettings.cs new file mode 100644 index 0000000..cefe00b --- /dev/null +++ b/Model/UserSettings.cs @@ -0,0 +1,58 @@ +namespace PettingZoo.Model +{ + public interface IUserSettingsSerializer + { + void Read(UserSettings settings); + void Write(UserSettings settings); + } + + + public class ConnectionWindowSettings + { + public string LastHost { get; set; } + public string LastVirtualHost { get; set; } + public int LastPort { get; set; } + public string LastUsername { get; set; } + public string LastPassword { get; set; } + + public string LastExchange { get; set; } + public string LastRoutingKey { get; set; } + + + public ConnectionWindowSettings() + { + LastHost = "localhost"; + LastPort = 5672; + LastVirtualHost = "/"; + LastUsername = "guest"; + LastPassword = "guest"; + + LastExchange = "amqp"; + LastRoutingKey = "#"; + } + } + + + public class UserSettings + { + public ConnectionWindowSettings ConnectionWindow { get; private set; } + + + private readonly IUserSettingsSerializer serializer; + + + public UserSettings(IUserSettingsSerializer serializer) + { + ConnectionWindow = new ConnectionWindowSettings(); + + this.serializer = serializer; + serializer.Read(this); + } + + + public void Save() + { + serializer.Write(this); + } + } +} diff --git a/PettingZoo.csproj b/PettingZoo.csproj index ed207e9..6b2b336 100644 --- a/PettingZoo.csproj +++ b/PettingZoo.csproj @@ -74,6 +74,7 @@ True + @@ -117,6 +118,7 @@ + @@ -145,20 +147,11 @@ True Resources.resx - - True - Settings.settings - True - PublicResXFileCodeGenerator Resources.Designer.cs - - SettingsSingleFileGenerator - Settings.Designer.cs - diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index ba0c262..4b0bc29 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -9,9 +9,6 @@ //------------------------------------------------------------------------------ namespace PettingZoo.Properties { - using System; - - /// /// A strongly-typed resource class, for looking up localized strings, etc. /// diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs deleted file mode 100644 index 02fe6eb..0000000 --- a/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace PettingZoo.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { - return defaultInstance; - } - } - } -} diff --git a/Properties/Settings.settings b/Properties/Settings.settings deleted file mode 100644 index 033d7a5..0000000 --- a/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/View/ConnectionWindow.xaml.cs b/View/ConnectionWindow.xaml.cs index 04d9afd..d0e94a0 100644 --- a/View/ConnectionWindow.xaml.cs +++ b/View/ConnectionWindow.xaml.cs @@ -1,5 +1,6 @@ using System.Windows; using System.Windows.Input; +using AutoMapper; using PettingZoo.Model; using PettingZoo.ViewModel; @@ -7,9 +8,27 @@ namespace PettingZoo.View { public class WindowConnectionInfoBuilder : IConnectionInfoBuilder { + private readonly UserSettings userSettings; + + private static readonly IMapper ConnectionInfoMapper = new MapperConfiguration(cfg => + { + cfg.RecognizeDestinationPrefixes("Last"); + cfg.RecognizePrefixes("Last"); + + cfg.CreateMap().ReverseMap(); + }).CreateMapper(); + + + public WindowConnectionInfoBuilder(UserSettings userSettings) + { + this.userSettings = userSettings; + } + + public ConnectionInfo Build() { - var viewModel = new ConnectionViewModel(ConnectionInfo.Default()); + var connectionInfo = ConnectionInfoMapper.Map(userSettings.ConnectionWindow); + var viewModel = new ConnectionViewModel(connectionInfo); var dialog = new ConnectionWindow(viewModel) { @@ -21,7 +40,14 @@ namespace PettingZoo.View dialog.DialogResult = true; }; - return dialog.ShowDialog().GetValueOrDefault() ? viewModel.ToModel() : null; + connectionInfo = dialog.ShowDialog().GetValueOrDefault() ? viewModel.ToModel() : null; + if (connectionInfo != null) + { + ConnectionInfoMapper.Map(connectionInfo, userSettings.ConnectionWindow); + userSettings.Save(); + } + + return connectionInfo; } } diff --git a/ViewModel/ConnectionViewModel.cs b/ViewModel/ConnectionViewModel.cs index eb04fef..367eb50 100644 --- a/ViewModel/ConnectionViewModel.cs +++ b/ViewModel/ConnectionViewModel.cs @@ -6,13 +6,11 @@ using PettingZoo.Model; namespace PettingZoo.ViewModel { - public class ConnectionViewModel + public class ConnectionViewModel : BaseViewModel { - private static readonly IMapper ModelMapper = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - }).CreateMapper(); + private static readonly IMapper ModelMapper = new MapperConfiguration(cfg => + cfg.CreateMap().ReverseMap() + ).CreateMapper(); private readonly DelegateCommand okCommand;