Files
DP44/Common/DTS.Common.Core/ServiceManager/ServiceManager.cs

142 lines
5.2 KiB
C#
Raw Normal View History

2026-04-17 14:55:32 -04:00
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
});
}
}
}