8 changed files with 196 additions and 70 deletions
@ -0,0 +1,71 @@
@@ -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 @@
@@ -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 @@
@@ -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