142 lines
5.2 KiB
Plaintext
142 lines
5.2 KiB
Plaintext
using System;
|
|
using System.Collections.Generic;
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
namespace DTS.Common.Core.ServiceManager
|
|
{
|
|
/// <summary>
|
|
/// Service manager allows a component to publish an implementation of a singleton interface (service) that
|
|
/// other components can retrieve reference to without knowing who published it
|
|
/// </summary>
|
|
public static class ServiceManager
|
|
{
|
|
/// <summary>
|
|
/// Stores all published interfaces
|
|
/// </summary>
|
|
private static readonly Dictionary<Type, object> Services = new Dictionary<Type, object>();
|
|
|
|
/// <summary>
|
|
/// Publishes a service
|
|
/// </summary>
|
|
/// <typeparam name="T">interface type of service</typeparam>
|
|
/// <param name="item">implementation of service</param>
|
|
public static void Publish<T>(T item) where T : class
|
|
{
|
|
if (Services.ContainsKey(typeof(T)))
|
|
{
|
|
throw new ArgumentException($"{typeof(T).Name}: has already been published");
|
|
}
|
|
|
|
Services.Add(typeof(T), item);
|
|
SendServicePublishedEvent(typeof(T), true);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Publishes a list of services
|
|
/// </summary>
|
|
/// <param name="item">class that will implement all the listed interfaces</param>
|
|
/// <param name="interfaceList">list of interfaces</param>
|
|
/// <param name="skipPublishedInterfaces">true to avoid errors on already published interfaces</param>
|
|
public static void Publish(object item, IEnumerable<Type> interfaceList, bool skipPublishedInterfaces)
|
|
{
|
|
foreach (var t in interfaceList)
|
|
{
|
|
if (Exists(t))
|
|
{
|
|
if (!skipPublishedInterfaces)
|
|
{
|
|
// service already published and caller indicated we should error out
|
|
throw new ArgumentException($"{t.Name}: has already been published");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// service doesn't exist so publish it
|
|
Services.Add(t, item);
|
|
SendServicePublishedEvent(t, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if specifed interface has been published, false if not
|
|
/// </summary>
|
|
/// <typeparam name="T">type of interface to check</typeparam>
|
|
/// <returns>true if interface has been published; false if not published</returns>
|
|
public static bool Exists<T>() where T : class
|
|
{
|
|
return Services.ContainsKey(typeof(T));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if specifed interface has been published, false if not
|
|
/// </summary>
|
|
/// <param name="t">type of interface to check</param>
|
|
/// <returns>true if interface has been published; false if not published</returns>
|
|
public static bool Exists(Type t)
|
|
{
|
|
return Services.ContainsKey(t);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns published service
|
|
/// </summary>
|
|
/// <typeparam name="T">interface type of service</typeparam>
|
|
/// <returns>published service or exception if not currently published</returns>
|
|
public static T Get<T>() where T : class
|
|
{
|
|
if (!Services.ContainsKey(typeof(T)))
|
|
{
|
|
throw new ArgumentException($"{typeof(T).Name}: has not been published");
|
|
}
|
|
|
|
return Services[typeof(T)] as T;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears specified service
|
|
/// </summary>
|
|
/// <typeparam name="T">interface type of service to clear</typeparam>
|
|
public static void Clear<T>() where T : class
|
|
{
|
|
if (Services.ContainsKey(typeof(T)))
|
|
{
|
|
SendServicePublishedEvent(typeof(T), false);
|
|
Services.Remove(typeof(T));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears list of published interfaces
|
|
/// </summary>
|
|
/// <param name="interfaceList">list of interfaces to unpublish</param>
|
|
public static void Clear(IEnumerable<Type> interfaceList)
|
|
{
|
|
foreach (var t in interfaceList)
|
|
{
|
|
if (!Services.ContainsKey(t)) continue;
|
|
|
|
SendServicePublishedEvent(t, false);
|
|
Services.Remove(t);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Sends a IServicePublishedEvent through the Event Manger to let subscribers know when
|
|
/// a service is published or unpublished
|
|
/// </summary>
|
|
/// <param name="type">type of interface</param>
|
|
/// <param name="published">true if being published, false if being unpublished</param>
|
|
private static void SendServicePublishedEvent(Type type, bool published)
|
|
{
|
|
EventManager.EventManager.Publish<IServicePublishedEvent>(new ServicePublishedEvent
|
|
{
|
|
IsPublished = published,
|
|
ServiceType = type
|
|
});
|
|
}
|
|
}
|
|
}
|