Browse Source

Introduce IPropertyService.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
16bb4b2e7f
  1. 4
      src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddNewNodeDialogTestFixture.cs
  2. 3
      src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewContainerTests.cs
  3. 5
      src/Main/Base/Project/Src/Services/SD.cs
  4. 2
      src/Main/Core/Project/ICSharpCode.Core.csproj
  5. 8
      src/Main/Core/Project/Src/AddInTree/CoreStartup.cs
  6. 63
      src/Main/Core/Project/Src/Services/PropertyService/IPropertyService.cs
  7. 3
      src/Main/Core/Project/Src/Services/PropertyService/Properties.cs
  8. 89
      src/Main/Core/Project/Src/Services/PropertyService/PropertyService.cs
  9. 159
      src/Main/Core/Project/Src/Services/PropertyService/PropertyServiceImpl.cs
  10. 2
      src/Main/Core/Project/Src/Services/StringParser/StringParser.cs

4
src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddNewNodeDialogTestFixture.cs

@ -6,9 +6,9 @@ using System.Drawing; @@ -6,9 +6,9 @@ using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.Core.WinForms;
using ICSharpCode.SharpDevelop;
using ICSharpCode.XmlEditor;
using NUnit.Framework;
using XmlEditor.Tests.Utils;
@ -36,7 +36,7 @@ namespace XmlEditor.Tests.Tree @@ -36,7 +36,7 @@ namespace XmlEditor.Tests.Tree
[TestFixtureSetUp]
public void SetUpFixture()
{
PropertyService.InitializeServiceForUnitTests();
SD.InitializeForUnitTests();
}
[SetUp]

3
src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewContainerTests.cs

@ -6,6 +6,7 @@ using System.Windows.Forms; @@ -6,6 +6,7 @@ using System.Windows.Forms;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.XmlEditor;
using NUnit.Framework;
using XmlEditor.Tests.Utils;
@ -34,7 +35,7 @@ namespace XmlEditor.Tests.Tree @@ -34,7 +35,7 @@ namespace XmlEditor.Tests.Tree
public void SetUpFixture()
{
// Need to initialize the properties service.
PropertyService.InitializeServiceForUnitTests();
SD.InitializeForUnitTests();
}
[SetUp]

5
src/Main/Base/Project/Src/Services/SD.cs

@ -35,7 +35,6 @@ namespace ICSharpCode.SharpDevelop @@ -35,7 +35,6 @@ namespace ICSharpCode.SharpDevelop
public static void InitializeForUnitTests()
{
var container = new SharpDevelopServiceContainer(ServiceSingleton.FallbackServiceProvider);
PropertyService.InitializeServiceForUnitTests();
ServiceSingleton.ServiceProvider = container;
}
@ -81,6 +80,10 @@ namespace ICSharpCode.SharpDevelop @@ -81,6 +80,10 @@ namespace ICSharpCode.SharpDevelop
get { return GetRequiredService<IMessageService>(); }
}
public static IPropertyService PropertyService {
get { return GetRequiredService<IPropertyService>(); }
}
public static IEditorControlService EditorControlService {
get { return GetRequiredService<IEditorControlService>(); }
}

2
src/Main/Core/Project/ICSharpCode.Core.csproj

@ -118,8 +118,10 @@ @@ -118,8 +118,10 @@
<Compile Include="Src\Services\MessageService\TextWriterMessageService.cs" />
<Compile Include="Src\Services\MessageService\IMessageService.cs" />
<Compile Include="Src\Services\MessageService\MessageService.cs" />
<Compile Include="Src\Services\PropertyService\IPropertyService.cs" />
<Compile Include="Src\Services\PropertyService\Properties.cs" />
<Compile Include="Src\Services\PropertyService\PropertyService.cs" />
<Compile Include="Src\Services\PropertyService\PropertyServiceImpl.cs" />
<Compile Include="Src\Services\ResourceService\ResourceNotFoundException.cs" />
<Compile Include="Src\Services\ResourceService\ResourceService.cs" />
<Compile Include="Src\Services\ServiceSingleton.cs" />

8
src/Main/Core/Project/Src/AddInTree/CoreStartup.cs

@ -203,9 +203,11 @@ namespace ICSharpCode.Core @@ -203,9 +203,11 @@ namespace ICSharpCode.Core
if (configDirectory == null)
configDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
applicationName);
PropertyService.InitializeService(configDirectory,
dataDirectory ?? Path.Combine(FileUtility.ApplicationRootPath, "data"),
propertiesName);
var container = ServiceSingleton.ServiceProvider.GetRequiredService<IServiceContainer>();
container.AddService(typeof(IPropertyService), new PropertyServiceImpl(
configDirectory,
dataDirectory ?? Path.Combine(FileUtility.ApplicationRootPath, "data"),
propertiesName));
ResourceService.InitializeService(Path.Combine(PropertyService.DataDirectory, "resources"));
StringParser.RegisterStringTagProvider(new AppNameProvider { appName = applicationName });
}

63
src/Main/Core/Project/Src/Services/PropertyService/IPropertyService.cs

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
namespace ICSharpCode.Core
{
/// <summary>
/// The property service.
/// </summary>
[FallbackService(typeof(PropertyServiceImpl))]
public interface IPropertyService : INotifyPropertyChanged
{
/// <summary>
/// Gets the configuration directory. (usually "%ApplicationData%\%ApplicationName%")
/// </summary>
/// <seealso cref="CoreStartup.ConfigDirectory"/>
string ConfigDirectory { get; }
/// <summary>
/// Gets the data directory (usually "ApplicationRootPath\data")
/// </summary>
/// <seealso cref="CoreStartup.DataDirectory"/>
string DataDirectory { get; }
/// <summary>
/// Gets the main properties container for this property service.
/// </summary>
Properties MainPropertiesContainer { get; }
/// <inheritdoc cref="Properties.Get{T}(string, T)"/>
T Get<T>(string key, T defaultValue);
/// <inheritdoc cref="Properties.NestedProperties"/>
Properties NestedProperties(string key);
/// <inheritdoc cref="Properties.SetNestedProperties"/>
void SetNestedProperties(string key, Properties nestedProperties);
/// <inheritdoc cref="Properties.Contains"/>
bool Contains(string key);
/// <inheritdoc cref="Properties.Set{T}(string, T)"/>
void Set<T>(string key, T value);
/// <inheritdoc cref="Properties.GetList"/>
IReadOnlyList<T> GetList<T>(string key);
/// <inheritdoc cref="Properties.SetList"/>
void SetList<T>(string key, IEnumerable<T> value);
/// <inheritdoc cref="Properties.Remove"/>
void Remove(string key);
/// <summary>
/// Saves the properties to disk.
/// </summary>
void Save();
}
}

3
src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

@ -122,6 +122,9 @@ namespace ICSharpCode.Core @@ -122,6 +122,9 @@ namespace ICSharpCode.Core
#endregion
#region Keys/Contains
/// <summary>
/// Gets the keys that are in use by this properties container.
/// </summary>
public IReadOnlyList<string> Keys {
get {
lock (syncRoot) {

89
src/Main/Core/Project/Src/Services/PropertyService/PropertyService.cs

@ -14,50 +14,20 @@ namespace ICSharpCode.Core @@ -14,50 +14,20 @@ namespace ICSharpCode.Core
{
public static class PropertyService
{
static string propertyFileName;
static string configDirectory;
static string dataDirectory;
static Properties properties;
public static bool Initialized {
get { return properties != null; }
static IPropertyService Service {
get { return ServiceSingleton.ServiceProvider.GetRequiredService<IPropertyService>(); }
}
/// <summary>
/// Initializes the service for unit-testing (reset properties to an empty property container).
/// Use <c>SD.InitializeForUnitTests()</c> instead, that initializes the property service and more.
/// </summary>
public static void InitializeServiceForUnitTests()
{
properties = null;
configDirectory = null;
dataDirectory = null;
propertyFileName = null;
properties = new Properties();
}
public static void InitializeService(string configDirectory, string dataDirectory, string propertiesName)
{
if (properties != null)
throw new InvalidOperationException("Service is already initialized.");
PropertyService.configDirectory = configDirectory;
PropertyService.dataDirectory = dataDirectory;
propertyFileName = propertiesName + ".xml";
LoadPropertiesFromStream(Path.Combine(configDirectory, propertyFileName));
static Properties properties {
get { return Service.MainPropertiesContainer; }
}
public static string ConfigDirectory {
get {
return configDirectory;
}
get { return Service.ConfigDirectory; }
}
public static string DataDirectory {
get {
return dataDirectory;
}
get { return Service.DataDirectory; }
}
/// <inheritdoc cref="Properties.Get{T}(string, T)"/>
@ -90,13 +60,6 @@ namespace ICSharpCode.Core @@ -90,13 +60,6 @@ namespace ICSharpCode.Core
return properties.Contains(key);
}
/// <summary>
/// Gets the main property container.
/// </summary>
internal static Properties PropertiesContainer {
get { return properties; }
}
/// <inheritdoc cref="Properties.Set{T}(string, T)"/>
public static void Set<T>(string key, T value)
{
@ -163,47 +126,9 @@ namespace ICSharpCode.Core @@ -163,47 +126,9 @@ namespace ICSharpCode.Core
properties.Remove(key);
}
static bool LoadPropertiesFromStream(string fileName)
{
if (!File.Exists(fileName)) {
properties = new Properties();
return false;
}
try {
using (LockPropertyFile()) {
properties = Properties.Load(fileName);
return true;
}
} catch (XmlException ex) {
MessageService.ShowError("Error loading properties: " + ex.Message + "\nSettings have been restored to default values.");
}
properties = new Properties();
return false;
}
public static void Save()
{
if (string.IsNullOrEmpty(configDirectory) || string.IsNullOrEmpty(propertyFileName))
throw new InvalidOperationException("No file name was specified on service creation");
string fileName = Path.Combine(configDirectory, propertyFileName);
using (LockPropertyFile()) {
properties.Save(fileName);
}
}
/// <summary>
/// Acquires an exclusive lock on the properties file so that it can be opened safely.
/// </summary>
public static IDisposable LockPropertyFile()
{
Mutex mutex = new Mutex(false, "PropertyServiceSave-30F32619-F92D-4BC0-BF49-AA18BF4AC313");
mutex.WaitOne();
return new CallbackOnDispose(
delegate {
mutex.ReleaseMutex();
mutex.Close();
});
Service.Save();
}
public static event PropertyChangedEventHandler PropertyChanged {

159
src/Main/Core/Project/Src/Services/PropertyService/PropertyServiceImpl.cs

@ -0,0 +1,159 @@ @@ -0,0 +1,159 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading;
using System.Xml;
namespace ICSharpCode.Core
{
sealed class PropertyServiceImpl : IPropertyService
{
string propertyFileName;
string configDirectory;
string dataDirectory;
Properties properties;
/// <summary>
/// Initializes the service for unit-testing (reset properties to an empty property container).
/// Use <c>SD.InitializeForUnitTests()</c> instead, that initializes the property service and more.
/// </summary>
public PropertyServiceImpl()
{
properties = new Properties();
}
public PropertyServiceImpl(string configDirectory, string dataDirectory, string propertiesName)
{
this.configDirectory = configDirectory;
this.dataDirectory = dataDirectory;
this.propertyFileName = propertiesName + ".xml";
LoadPropertiesFromStream(Path.Combine(configDirectory, propertyFileName));
}
public string ConfigDirectory {
get {
return configDirectory;
}
}
public string DataDirectory {
get {
return dataDirectory;
}
}
/// <inheritdoc cref="Properties.Get{T}(string, T)"/>
public T Get<T>(string key, T defaultValue)
{
return properties.Get(key, defaultValue);
}
[Obsolete("Use the NestedProperties method instead", true)]
public Properties Get(string key, Properties defaultValue)
{
return properties.Get(key, defaultValue);
}
/// <inheritdoc cref="Properties.NestedProperties"/>
public Properties NestedProperties(string key)
{
return properties.NestedProperties(key);
}
/// <inheritdoc cref="Properties.SetNestedProperties"/>
public void SetNestedProperties(string key, Properties nestedProperties)
{
properties.SetNestedProperties(key, nestedProperties);
}
/// <inheritdoc cref="Properties.Contains"/>
public bool Contains(string key)
{
return properties.Contains(key);
}
/// <inheritdoc cref="Properties.Set{T}(string, T)"/>
public void Set<T>(string key, T value)
{
properties.Set(key, value);
}
/// <inheritdoc cref="Properties.GetList"/>
public IReadOnlyList<T> GetList<T>(string key)
{
return properties.GetList<T>(key);
}
/// <inheritdoc cref="Properties.SetList"/>
public void SetList<T>(string key, IEnumerable<T> value)
{
properties.SetList(key, value);
}
/// <inheritdoc cref="Properties.Remove"/>
public void Remove(string key)
{
properties.Remove(key);
}
bool LoadPropertiesFromStream(string fileName)
{
if (!File.Exists(fileName)) {
properties = new Properties();
return false;
}
try {
using (LockPropertyFile()) {
properties = Properties.Load(fileName);
return true;
}
} catch (XmlException ex) {
MessageService.ShowError("Error loading properties: " + ex.Message + "\nSettings have been restored to default values.");
}
properties = new Properties();
return false;
}
public void Save()
{
if (string.IsNullOrEmpty(configDirectory) || string.IsNullOrEmpty(propertyFileName))
throw new InvalidOperationException("No file name was specified on service creation");
string fileName = Path.Combine(configDirectory, propertyFileName);
using (LockPropertyFile()) {
properties.Save(fileName);
}
}
/// <summary>
/// Acquires an exclusive lock on the properties file so that it can be opened safely.
/// </summary>
public IDisposable LockPropertyFile()
{
Mutex mutex = new Mutex(false, "PropertyServiceSave-30F32619-F92D-4BC0-BF49-AA18BF4AC313");
mutex.WaitOne();
return new CallbackOnDispose(
delegate {
mutex.ReleaseMutex();
mutex.Close();
});
}
public event PropertyChangedEventHandler PropertyChanged {
add { properties.PropertyChanged += value; }
remove { properties.PropertyChanged -= value; }
}
public Properties MainPropertiesContainer {
get { return properties; }
}
}
}

2
src/Main/Core/Project/Src/Services/StringParser/StringParser.cs

@ -224,7 +224,7 @@ namespace ICSharpCode.Core @@ -224,7 +224,7 @@ namespace ICSharpCode.Core
defaultValue = propertyName.Substring(pos + 2);
propertyName = propertyName.Substring(0, pos);
}
Properties properties = PropertyService.PropertiesContainer;
Properties properties = ServiceSingleton.ServiceProvider.GetRequiredService<IPropertyService>().MainPropertiesContainer;
pos = propertyName.IndexOf('/');
while (pos >= 0) {
properties = properties.NestedProperties(propertyName.Substring(0, pos));

Loading…
Cancel
Save