diff --git a/Core/DependencyInjector.cs b/Core/DependencyInjector.cs new file mode 100644 index 00000000..3ac74484 --- /dev/null +++ b/Core/DependencyInjector.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; + +namespace UIComponents.Core +{ + public class DependencyInjector + { + private static readonly Dictionary InstantiatedInstanceDictionary + = new Dictionary(); + + private readonly Dictionary _dependencyDictionary + = new Dictionary(); + + internal void AddProvidersFromDependencies(IEnumerable dependencyAttributes) + { + foreach (var dependencyAttribute in dependencyAttributes) + { + var type = dependencyAttribute.DependencyType; + var providerType = dependencyAttribute.ProviderType; + + if (!_dependencyDictionary.ContainsKey(type)) + _dependencyDictionary[type] = CreateInstance(providerType); + } + } + + private static object CreateInstance(Type providerType) + { + object instance; + + if (InstantiatedInstanceDictionary.ContainsKey(providerType)) + { + instance = InstantiatedInstanceDictionary[providerType]; + } + else + { + instance = Activator.CreateInstance(providerType); + InstantiatedInstanceDictionary[providerType] = instance; + } + + return instance; + } + + public void SetProvider(T instance) + { + _dependencyDictionary[typeof(T)] = instance; + } + + public T Provide() + { + var type = typeof(T); + + if (!_dependencyDictionary.ContainsKey(type)) + { + var value = (T) CreateInstance(type); + SetProvider(value); + return value; + } + + return (T) _dependencyDictionary[type]; + } + } +} \ No newline at end of file diff --git a/Core/DependencyInjector.cs.meta b/Core/DependencyInjector.cs.meta new file mode 100644 index 00000000..648698e4 --- /dev/null +++ b/Core/DependencyInjector.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6a6345f5ab0b450ba101ceb0a2565ced +timeCreated: 1651076028 \ No newline at end of file diff --git a/Core/InjectDependencyAttribute.cs b/Core/InjectDependencyAttribute.cs new file mode 100644 index 00000000..86621c8b --- /dev/null +++ b/Core/InjectDependencyAttribute.cs @@ -0,0 +1,20 @@ +using System; +using JetBrains.Annotations; + +namespace UIComponents.Core +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + [BaseTypeRequired(typeof(UIComponent))] + public class InjectDependencyAttribute : Attribute + { + public readonly Type DependencyType; + + public readonly Type ProviderType; + + public InjectDependencyAttribute(Type dependency, Type provider) + { + DependencyType = dependency; + ProviderType = provider; + } + } +} \ No newline at end of file diff --git a/Core/InjectDependencyAttribute.cs.meta b/Core/InjectDependencyAttribute.cs.meta new file mode 100644 index 00000000..caf3d033 --- /dev/null +++ b/Core/InjectDependencyAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bab23e4a76cb47d3addf2615c9826174 +timeCreated: 1651088015 \ No newline at end of file diff --git a/Core/UIComponent.cs b/Core/UIComponent.cs index 8aada012..13287889 100644 --- a/Core/UIComponent.cs +++ b/Core/UIComponent.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using JetBrains.Annotations; using UnityEditor; using UnityEngine; @@ -14,31 +15,39 @@ public abstract class UIComponent : VisualElement private readonly StylesheetAttribute[] _stylesheetAttributes; + private static readonly Dictionary InjectorDictionary = + new Dictionary(); + + public static void SetDependencyProvider(TDependency provider) + { + var componentType = typeof(TComponent); + + if (!InjectorDictionary.ContainsKey(componentType)) + InjectorDictionary.Add(componentType, new DependencyInjector()); + + InjectorDictionary[componentType].SetProvider(provider); + } + protected UIComponent() { _componentType = GetType(); _layoutAttribute = GetLayoutAttribute(); - _stylesheetAttributes = GetStylesheetAttributes(); + _stylesheetAttributes = GetAttributes(); + + var type = GetType(); + + if (!InjectorDictionary.ContainsKey(type)) + InjectorDictionary.Add(type, new DependencyInjector()); + + InjectorDictionary[type].AddProvidersFromDependencies(GetAttributes()); + LoadLayout(); LoadStyles(); } - [CanBeNull] - private LayoutAttribute GetLayoutAttribute() - { - var layoutAttributes = - (LayoutAttribute[]) _componentType.GetCustomAttributes(typeof(LayoutAttribute), true); - - if (layoutAttributes.Length == 0) - return null; - - return layoutAttributes[0]; - } - - private StylesheetAttribute[] GetStylesheetAttributes() + protected T Provide() { - return (StylesheetAttribute[]) - _componentType.GetCustomAttributes(typeof(StylesheetAttribute), true); + return InjectorDictionary[_componentType].Provide(); } [CanBeNull] @@ -62,6 +71,22 @@ protected virtual StyleSheet[] GetStyleSheets() return loadedStyleSheets; } + + [CanBeNull] + private LayoutAttribute GetLayoutAttribute() + { + var layoutAttributes = GetAttributes(); + + if (layoutAttributes.Length == 0) + return null; + + return layoutAttributes[0]; + } + + private T[] GetAttributes() where T : Attribute + { + return (T[]) _componentType.GetCustomAttributes(typeof(T), true); + } private void LoadLayout() {