Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extract interface from ServiceManager, convert some methods to extens…

…ion methods, implement caching for GetService<T>() method, and make some methods virtual
  • Loading branch information...
commit a076f5af3ac0c5dc12d475475b464e0bc0b2b3b8 1 parent e9816e3
@cdhowie authored
View
5 Cdh.Toolkit.Services/Cdh.Toolkit.Services.csproj
@@ -54,12 +54,17 @@
<Compile Include="ServiceManager.cs" />
<Compile Include="ThreadedService.cs" />
<Compile Include="LightService.cs" />
+ <Compile Include="IServiceManager.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Cdh.Toolkit.Collections\Cdh.Toolkit.Collections.csproj">
<Project>{A2E1EDA8-78B8-4717-8B75-0D1A2AC47F15}</Project>
<Name>Cdh.Toolkit.Collections</Name>
</ProjectReference>
+ <ProjectReference Include="..\Cdh.Toolkit.Extensions\Cdh.Toolkit.Extensions.csproj">
+ <Project>{1F804DDB-FFB0-4D57-B5DD-03389FAC1836}</Project>
+ <Name>Cdh.Toolkit.Extensions</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
View
42 Cdh.Toolkit.Services/IServiceManager.cs
@@ -0,0 +1,42 @@
+using System;
+using Cdh.Toolkit.Extensions;
+using System.Collections.Generic;
+
+namespace Cdh.Toolkit.Services
+{
+ public interface IServiceManager
+ {
+ void RegisterService(IService service);
+ void UnregisterService(IService service);
+
+ IEnumerable<T> GetServices<T>() where T : IService;
+ T GetService<T>() where T : IService;
+ }
+
+ public static class ServiceManagerExtensions
+ {
+ public static T RequireService<T>(this IServiceManager serviceManager) where T : IService
+ {
+ Check.ArgumentIsNotNull(serviceManager, "serviceManager");
+
+ var service = serviceManager.GetService<T>();
+
+ if (service == null) {
+ throw new InvalidOperationException(string.Format(
+ "There is not exactly one service of type {0} registered.", typeof(T).FullName));
+ }
+
+ return service;
+ }
+
+ public static void RegisterAndStartService(this IServiceManager serviceManager, IService service)
+ {
+ Check.ArgumentIsNotNull(serviceManager, "serviceManager");
+ Check.ArgumentIsNotNull(service, "service");
+
+ serviceManager.RegisterService(service);
+ service.Start();
+ }
+ }
+}
+
View
66 Cdh.Toolkit.Services/ServiceManager.cs
@@ -30,58 +30,80 @@
using System.Text;
using Cdh.Toolkit.Collections;
+using System.Threading;
+using Cdh.Toolkit.Extensions.ReaderWriterLockSlim;
namespace Cdh.Toolkit.Services
{
- public class ServiceManager
+ public class ServiceManager : IServiceManager
{
- private SynchronizedCollection<IService> services =
- new SynchronizedCollection<IService>(new HashSet<IService>(), EnumerateBehavior.Lock);
+ protected ReaderWriterLockSlim Lock { get; private set; }
+
+ protected ICollection<IService> ServiceCollection { get; private set; }
public ICollection<IService> Services { get; private set; }
+ private Dictionary<Type, IService> serviceCache = new Dictionary<Type, IService>();
+
public ServiceManager()
{
- Services = new ReadOnlyCollection<IService>(services);
+ Lock = new ReaderWriterLockSlim();
+
+ ServiceCollection = new HashSet<IService>();
+
+ Services = new ReadOnlyCollection<IService>(new SynchronizedCollection<IService>(ServiceCollection, EnumerateBehavior.Lock, Lock));
}
- public void RegisterService(IService service)
+ public virtual void RegisterService(IService service)
{
if (service == null)
throw new ArgumentNullException("service");
- services.Add(service);
- }
+ using (Lock.Write()) {
+ ServiceCollection.Add(service);
- public void RegisterAndStartService(IService service)
- {
- RegisterService(service);
- service.Start();
+ PurgeCache();
+ }
}
- public void UnregisterService(IService service)
+ public virtual void UnregisterService(IService service)
{
if (service == null)
throw new ArgumentNullException("service");
- services.Remove(service);
+ using (Lock.Write()) {
+ ServiceCollection.Remove(service);
+
+ PurgeCache();
+ }
}
- public T GetService<T>() where T : IService
+ protected void PurgeCache()
{
- return services.OfType<T>().SingleOrDefault();
+ serviceCache.Clear();
}
- public T RequireService<T>() where T : IService
+ public virtual IEnumerable<T> GetServices<T>() where T : IService
{
- var service = GetService<T>();
-
- if (service == null) {
- throw new InvalidOperationException(string.Format(
- "Required service type {0} not registered.", typeof(T).FullName));
+ using (Lock.Read()) {
+ return ServiceCollection.OfType<T>().ToList();
}
+ }
+
+ public virtual T GetService<T>() where T : IService
+ {
+ using (Lock.Read()) {
+ IService cachedService;
+ if (serviceCache.TryGetValue(typeof(T), out cachedService)) {
+ return (T)cachedService;
+ }
+
+ var service = GetServices<T>().SingleOrDefault();
- return service;
+ serviceCache[typeof(T)] = service;
+
+ return service;
+ }
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.