Last active
March 29, 2020 10:36
-
-
Save Arlodotexe/0527522ff54ca3839bf51c61c89cce83 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace AppName | |
{ | |
public class InstanceContainer | |
{ | |
public InstanceContainer(WeakReference<object> instance) | |
{ | |
Instance = instance; | |
} | |
public InstanceContainer(WeakReference<object> instance, string contextIdentifier, bool isPrimary) | |
{ | |
Instance = instance; | |
ContextIdentifier = contextIdentifier; | |
IsPrimary = isPrimary; | |
} | |
public InstanceContainer(WeakReference<object> instance, bool isPrimary) | |
{ | |
Instance = instance; | |
IsPrimary = isPrimary; | |
} | |
public WeakReference<object> Instance; | |
/// <summary> | |
/// Identifies an instance based on a declared context | |
/// </summary> | |
public string ContextIdentifier; | |
/// <summary> | |
/// Prefferred instance of an object | |
/// </summary> | |
public bool IsPrimary; | |
} | |
public static class InstanceLocator | |
{ | |
public static List<InstanceContainer> Instances { get; set; } = new List<InstanceContainer>(); | |
public static IEnumerable<T> GetAll<T>() | |
{ | |
return Instances.Where(i => i.Instance.TryGetTarget(out object data) && data is T)?.Select(i => | |
{ | |
i.Instance.TryGetTarget(out object returnVal); | |
return (T)returnVal; | |
}); | |
} | |
public static void ExecAll<T>(Action<T> action) | |
{ | |
foreach (var reference in Instances.Where(i => i.Instance.TryGetTarget(out object data) && data is T)) | |
{ | |
reference.Instance.TryGetTarget(out object output); | |
action((T)output); | |
} | |
} | |
public static async Task ExecAllAsync<T>(Func<T, Task> action) | |
{ | |
foreach (var reference in Instances.Where(i => i.Instance.TryGetTarget(out object data) && data is T)) | |
{ | |
reference.Instance.TryGetTarget(out object output); | |
await action((T)output); | |
} | |
} | |
public static T GetByContext<T>(object contextIdentifier) | |
{ | |
object returnVal = null; | |
foreach (var reference in Instances.Where(i => i.Instance.TryGetTarget(out object data) && data is T)) | |
{ | |
if (reference.ContextIdentifier == contextIdentifier.ToString()) | |
{ | |
reference.Instance.TryGetTarget(out returnVal); | |
break; | |
} | |
} | |
return (T)returnVal; | |
} | |
public static T GetPrimary<T>() | |
{ | |
object returnVal = null; | |
foreach (var reference in Instances.Where(i => i.Instance.TryGetTarget(out object data) && data is T)) | |
{ | |
if (reference.IsPrimary) | |
{ | |
reference.Instance.TryGetTarget(out returnVal); | |
break; | |
} | |
} | |
return (T)returnVal; | |
} | |
public static void Add<T>(T instance, bool isPrimary = false) | |
{ | |
Instances.Add(new InstanceContainer(new WeakReference<object>(instance), isPrimary)); | |
} | |
public static void Add<T>(T instance, object contextIdentifier, bool isPrimary = false) | |
{ | |
if (Instances.Any(i => i.ContextIdentifier == contextIdentifier.ToString())) | |
throw new InvalidOperationException($"Identifier \"{contextIdentifier}\" already exists"); | |
Instances.Add(new InstanceContainer(new WeakReference<object>(instance), contextIdentifier.ToString(), isPrimary)); | |
} | |
public static void Remove<T>(object contextIdentifier) | |
{ | |
Instances.Remove(Instances.FirstOrDefault(i => i.Instance.TryGetTarget(out object data) && data is T && i.ContextIdentifier == contextIdentifier.ToString())); | |
} | |
public static void RemoveAll<T>() | |
{ | |
Instances.RemoveAll(i => i.Instance.TryGetTarget(out object data) && data is T); | |
} | |
public static void SelectPrimary(object contextIdentifier) | |
{ | |
foreach (var instanceContainer in Instances) | |
{ | |
// Sets to true if the context identifier matches, sets to false if not | |
instanceContainer.IsPrimary = | |
instanceContainer.ContextIdentifier == contextIdentifier.ToString(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment