8 changed files with 196 additions and 70 deletions
@ -0,0 +1,71 @@ |
|||||||
|
// 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.ComponentModel.Design; |
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.Core.Services; |
||||||
|
using ICSharpCode.SharpDevelop.Gui; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Static entry point for retrieving SharpDevelop services.
|
||||||
|
/// </summary>
|
||||||
|
public static class SD |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets the main service container for SharpDevelop.
|
||||||
|
/// </summary>
|
||||||
|
public static IServiceContainer Services { |
||||||
|
get { return GetRequiredService<IServiceContainer>(); } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a service. Returns null if service is not found.
|
||||||
|
/// </summary>
|
||||||
|
public static T GetService<T>() where T : class |
||||||
|
{ |
||||||
|
return ServiceManager.Instance.GetService<T>(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a service. Returns null if service is not found.
|
||||||
|
/// </summary>
|
||||||
|
public static T GetRequiredService<T>() where T : class |
||||||
|
{ |
||||||
|
return ServiceManager.Instance.GetRequiredService<T>(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the workbench.
|
||||||
|
/// </summary>
|
||||||
|
public static IWorkbench Workbench { |
||||||
|
get { |
||||||
|
var workbench = WorkbenchSingleton.Workbench; |
||||||
|
if (workbench == null) |
||||||
|
throw new ServiceNotFoundException("Workbench"); |
||||||
|
return workbench; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the status bar.
|
||||||
|
/// </summary>
|
||||||
|
public static IStatusBarService StatusBar { |
||||||
|
get { return Workbench.StatusBar; } |
||||||
|
} |
||||||
|
|
||||||
|
public static ILoggingService LoggingService { |
||||||
|
get { return GetRequiredService<ILoggingService>(); } |
||||||
|
} |
||||||
|
|
||||||
|
public static IMessageService MessageService { |
||||||
|
get { return GetRequiredService<IMessageService>(); } |
||||||
|
} |
||||||
|
|
||||||
|
public static IAnalyticsMonitor AnalyticsMonitor { |
||||||
|
get { return GetRequiredService<IAnalyticsMonitor>(); } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,115 @@ |
|||||||
|
// 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.ComponentModel.Design; |
||||||
|
using System.Linq; |
||||||
|
using System.Collections.Generic; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// A thread-safe service container class.
|
||||||
|
/// </summary>
|
||||||
|
public class ThreadSafeServiceContainer : IServiceProvider, IServiceContainer, IDisposable |
||||||
|
{ |
||||||
|
Dictionary<Type, object> services = new Dictionary<Type, object>(); |
||||||
|
|
||||||
|
public ThreadSafeServiceContainer() |
||||||
|
{ |
||||||
|
services.Add(typeof(ThreadSafeServiceContainer), this); |
||||||
|
services.Add(typeof(IServiceContainer), this); |
||||||
|
} |
||||||
|
|
||||||
|
public object GetOrCreateService(Type type, Func<object> serviceCreator) |
||||||
|
{ |
||||||
|
lock (services) { |
||||||
|
object instance; |
||||||
|
if (!services.TryGetValue(type, out instance)) { |
||||||
|
instance = serviceCreator(); |
||||||
|
services.Add(type, instance); |
||||||
|
} |
||||||
|
return instance; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void TryAddService(Type type, object instance) |
||||||
|
{ |
||||||
|
lock (services) { |
||||||
|
if (!services.ContainsKey(type)) |
||||||
|
services.Add(type, instance); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public object GetService(Type serviceType) |
||||||
|
{ |
||||||
|
object instance; |
||||||
|
lock (services) { |
||||||
|
if (!services.TryGetValue(serviceType, out instance)) |
||||||
|
return null; |
||||||
|
} |
||||||
|
ServiceCreatorCallback callback = instance as ServiceCreatorCallback; |
||||||
|
if (callback == null) |
||||||
|
return instance; |
||||||
|
object newInstance = callback(this, serviceType); |
||||||
|
lock (services) { |
||||||
|
if (services.TryGetValue(serviceType, out instance) && ReferenceEquals(instance, callback)) { |
||||||
|
services[serviceType] = newInstance; |
||||||
|
return newInstance; |
||||||
|
} |
||||||
|
} |
||||||
|
// concurrent modification while running the callback (most likely another thread ran the callback first):
|
||||||
|
IDisposable disposable = newInstance as IDisposable; |
||||||
|
if (disposable != null) |
||||||
|
disposable.Dispose(); |
||||||
|
return GetService(serviceType); // retry
|
||||||
|
} |
||||||
|
|
||||||
|
public void Dispose() |
||||||
|
{ |
||||||
|
IDisposable[] disposables; |
||||||
|
lock (services) { |
||||||
|
disposables = services.Values.OfType<IDisposable>().ToArray(); |
||||||
|
services.Clear(); |
||||||
|
} |
||||||
|
foreach (IDisposable disposable in disposables) |
||||||
|
disposable.Dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
public void AddService(Type serviceType, object serviceInstance) |
||||||
|
{ |
||||||
|
lock (services) { |
||||||
|
services.Add(serviceType, serviceInstance); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void AddService(Type serviceType, object serviceInstance, bool promote) |
||||||
|
{ |
||||||
|
AddService(serviceType, serviceInstance); |
||||||
|
} |
||||||
|
|
||||||
|
public void AddService(Type serviceType, ServiceCreatorCallback callback) |
||||||
|
{ |
||||||
|
lock (services) { |
||||||
|
services.Add(serviceType, callback); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote) |
||||||
|
{ |
||||||
|
AddService(serviceType, callback); |
||||||
|
} |
||||||
|
|
||||||
|
public void RemoveService(Type serviceType) |
||||||
|
{ |
||||||
|
lock (services) { |
||||||
|
services.Remove(serviceType); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void RemoveService(Type serviceType, bool promote) |
||||||
|
{ |
||||||
|
RemoveService(serviceType); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,64 +0,0 @@ |
|||||||
// 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.Linq; |
|
||||||
using System.Collections.Generic; |
|
||||||
|
|
||||||
namespace ICSharpCode.SharpDevelop |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A thread-safe service container class.
|
|
||||||
/// </summary>
|
|
||||||
public class ThreadSafeServiceContainer : IServiceProvider, IDisposable |
|
||||||
{ |
|
||||||
Dictionary<Type, object> services = new Dictionary<Type, object>(); |
|
||||||
|
|
||||||
public ThreadSafeServiceContainer() |
|
||||||
{ |
|
||||||
services.Add(typeof(ThreadSafeServiceContainer), this); |
|
||||||
} |
|
||||||
|
|
||||||
public object GetOrCreateService(Type type, Func<object> serviceCreator) |
|
||||||
{ |
|
||||||
lock (services) { |
|
||||||
object instance; |
|
||||||
if (!services.TryGetValue(type, out instance)) { |
|
||||||
instance = serviceCreator(); |
|
||||||
services.Add(type, instance); |
|
||||||
} |
|
||||||
return instance; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void TryAddService(Type type, object instance) |
|
||||||
{ |
|
||||||
lock (services) { |
|
||||||
if (!services.ContainsKey(type)) |
|
||||||
services.Add(type, instance); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public object GetService(Type type) |
|
||||||
{ |
|
||||||
lock (services) { |
|
||||||
object instance; |
|
||||||
if (services.TryGetValue(type, out instance)) |
|
||||||
return instance; |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void Dispose() |
|
||||||
{ |
|
||||||
IDisposable[] disposables; |
|
||||||
lock (services) { |
|
||||||
disposables = services.Values.OfType<IDisposable>().ToArray(); |
|
||||||
services.Clear(); |
|
||||||
} |
|
||||||
foreach (IDisposable disposable in disposables) |
|
||||||
disposable.Dispose(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue