Skip to content

Instantly share code, notes, and snippets.

@FleshMobProductions
Last active March 7, 2024 07:41
Show Gist options
  • Save FleshMobProductions/5588306c3d554154c65b6b9599eef8af to your computer and use it in GitHub Desktop.
Save FleshMobProductions/5588306c3d554154c65b6b9599eef8af to your computer and use it in GitHub Desktop.
An abstraction for accessing singleton instances in C# (made for the use in Unity3D)
using System;
using System.Collections.Generic;
namespace FMPUtils
{
public static class SingletonProvider
{
private static readonly Dictionary<Type, Func<object>> instanceAccessors = new Dictionary<Type, Func<object>>();
public static void Clear()
{
instanceAccessors.Clear();
}
public static void AddSingleton<T>(Func<T> accessorMethod, bool overwriteIfAccessorExists = true) where T : class
{
if (accessorMethod == null) return;
if (!overwriteIfAccessorExists && instanceAccessors.ContainsKey(typeof(T))) return;
instanceAccessors[typeof(T)] = accessorMethod;
}
public static T Get<T>() where T : class
{
if (instanceAccessors.TryGetValue(typeof(T), out Func<object> accessorMethod))
{
return accessorMethod?.Invoke() as T;
}
return default(T);
}
}
}
public class SingletonProviderUsageExample
{
public interface IMessenger
{
void SendMessage();
}
public class Messenger : IMessenger
{
public static Messenger Instance => instance;
private static readonly Messenger instance = new Messenger();
private Messenger() { }
public void SendMessage() { }
}
void DemonstrateMethods()
{
// Register accessor method for singleton:
SingletonProvider.AddSingleton<IMessenger>(() => Messenger.Instance);
// Retrieve singleton instance for interface type:
var messenger = SingletonProvider.Get<IMessenger>();
}
}
@FleshMobProductions
Copy link
Author

Note: I was told that the concept of this DI container is usually called a "ServiceProvider", but even if this doesn't just work for Singletons I'll keep the existing name because I am under the impression that people that use Unity3D might rather look for the term "Singleton.." than "ServiceProvider"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment