Skip to content

Instantly share code, notes, and snippets.

@JSandusky
Last active February 11, 2022 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JSandusky/75790568781b9ba4c80134f9037cb5a9 to your computer and use it in GitHub Desktop.
Save JSandusky/75790568781b9ba4c80134f9037cb5a9 to your computer and use it in GitHub Desktop.
Singleton access manager
/// <summary>
/// While null it will automatically check to seek out
/// </summary>
/// <typeparam name="T">Type of the object we we to acquire</typeparam>
public class IOCDependency<T> where T : class
{
public delegate void DependencyResolved(IOCDependency<T> self);
public event DependencyResolved DependencyResolvedHandler = delegate { };
T object_;
object relTo_;
int iocGeneration_ = -1; // always start as "don't care generation"
/// <summary>
/// Construct as a top-level dependency
/// </summary>
public IOCDependency()
{
}
/// <summary>
/// Construct a relative dependency.
/// </summary>
/// <param name="relTo">object we need to key off of to resolve the dependency</param>
public IOCDependency(object relTo)
{
relTo_ = relTo;
}
public bool IsValid { get { return Object != null; } }
public T Object {
get
{
if (object_ != null)
return object_;
// Don't have it so we need to find it
if (relTo_ != null)
object_ = IOCLite.GetRelativeObject<T>(relTo_, iocGeneration_);
else
object_ = IOCLite.GetObject<T>(iocGeneration_);
// Update our generation so we skip early
iocGeneration_ = IOCLite.Generation();
// We now have it so send an event
if (object_ != null)
DependencyResolvedHandler(this);
return object_;
}
}
}
/// <summary>
/// Objects are registered into the IoCLite container for lookup by IoCDependencies
/// </summary>
public class IOCLite
{
static IOCLite inst_;
List<object> objects_ = new List<object>();
Dictionary<object, List<object>> relativeObjects_ = new Dictionary<object, List<object>>();
int iocGeneration_ = 0;
/// <summary>
/// Prevent unintended construction.
/// </summary>
private IOCLite() { }
/// <summary>
/// Access static singleton, initialize if necessary
/// </summary>
/// <returns>Reference to the singleton instance</returns>
public static IOCLite inst()
{
if (inst_ == null)
inst_ = new IOCLite();
return inst_;
}
public static int Generation() { return inst().iocGeneration_; }
/// <summary>
/// Register an object for tracking in the container.
/// </summary>
/// <param name="obj">Object to store</param>
public static void Register(object obj)
{
inst().objects_.Add(obj);
inst().iocGeneration_ += 1;
}
/// <summary>
/// Brute force removal
/// </summary>
/// <param name="obj">Object to remove, if this object is a key then EVERYTHING will be removed</param>
public static void Unregister(object obj)
{
inst().objects_.Remove(obj);
inst().relativeObjects_.Remove(obj);
foreach (var key in inst().relativeObjects_)
key.Value.Remove(obj);
}
/// <summary>
/// Register an object with a key for relative lookup.
/// </summary>
/// <param name="relTo">Key to be used for the given "obj"</param>
/// <param name="obj">Object to register into the table</param>
public static void RegisterRelative(object relTo, object obj)
{
inst().iocGeneration_ += 1;
var relObjects = inst().relativeObjects_;
if (relObjects.ContainsKey(relTo))
relObjects[relTo].Add(obj);
else
{
relObjects[relTo] = new List<object>();
relObjects[relTo].Add(obj);
}
}
/// <summary>
/// Retrieve an object reference from storage.
/// </summary>
/// <typeparam name="T">Type of the object to be sought</typeparam>
/// <param name="generation">Optional 'generation' key</param>
/// <returns>The found object or null</returns>
public static T GetObject<T>(int generation = -1) where T : class
{
if (generation != -1 && generation >= inst().iocGeneration_)
return null;
Type tType = typeof(T);
for (int i = 0; i < inst().objects_.Count; ++i)
{
if (inst().objects_[i].GetType() == tType)
return inst().objects_[i] as T;
}
return null;
}
/// <summary>
/// Grab an object relative to a given key object.
/// </summary>
/// <typeparam name="T">Type of object to acquire</typeparam>
/// <param name="relTo">"Key" object used for looking up the right object</param>
/// <param name="generation">A generation index to use for verifying</param>
/// <returns>The found object or null</returns>
public static T GetRelativeObject<T>(object relTo, int generation = -1) where T : class
{
if (generation != -1 && generation >= inst().iocGeneration_)
return null;
Type tType = typeof(T);
var dict = inst().relativeObjects_;
if (dict.ContainsKey(relTo))
{
var objects = dict[relTo];
for (int i = 0; i < objects.Count; ++i)
{
if (objects[i].GetType() == tType)
return objects[i] as T;
}
}
return null;
}
}
#region IOC Setup
IOCLite.Register(PluginManager.inst());
IOCLite.Register(DocumentManager);
IOCLite.Register(selectionContext_);
// For direct access, plus possibility to reroute if needed later
IOCLite.Register(UserData.inst().GeneralSettings);
IOCLite.Register(UserData.inst().ViewportSettings);
IOCLite.Register(UserData.inst().MeshingSettings);
IOCLite.Register(UserData.inst().UVGenerationSettings);
IOCLite.Register(UserData.inst().BitNames);
// DO NOT DO! Without NGen this is WAY too slow
//IOCInitializedAttribute.Execute();
#endregion
//================================
// Get object via:
new IOCDependency<DocumentManager>().Object.___YOUR_CODE_HERE___
// Or store the instance
IOCDependency<DocumentManager> docMan = new IOCDependency<DocumentManager>();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment