diff --git a/.gitignore b/.gitignore index abebf93..184ba9a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,7 @@ sysinfo.txt *.apk #*.unitypackage -.DS_Store \ No newline at end of file +.DS_Store + +# Rider +/.idea/ \ No newline at end of file diff --git a/Runtime/Core/API/Pin.LoadScene.cs b/Runtime/Core/API/Pin.LoadScene.cs new file mode 100644 index 0000000..c8aed37 --- /dev/null +++ b/Runtime/Core/API/Pin.LoadScene.cs @@ -0,0 +1,46 @@ +// PinInject, Maxwell Keonwoo Kang , 2022 + +using System; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace Cathei.PinInject +{ + public static partial class Pin + { + internal static ContextConfiguration sceneContextConfig = null; + + /// + /// Load and inject config a Scene. + /// + public static void LoadScene(string sceneName, LoadSceneMode loadSceneMode, ContextConfiguration config = null) + { + sceneContextConfig = config; + SceneManager.LoadScene(sceneName, loadSceneMode); + } + + /// + /// Load and inject config a Scene. + /// + /// + /// Note: Calling this method in parallel may result in improper injection of the Configuration. + /// + public static AsyncOperation LoadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, ContextConfiguration config = null) + { + sceneContextConfig = config; + return SceneManager.LoadSceneAsync(sceneName, loadSceneMode); + } + + /// + /// Load and inject config a Scene. + /// + /// + /// Note: Calling this method in parallel may result in improper injection of the Configuration. + /// + public static T LoadSceneAsync(Func loadSceneFunc, ContextConfiguration config = null) + { + sceneContextConfig = config; + return loadSceneFunc(); + } + } +} \ No newline at end of file diff --git a/Runtime/Core/API/Pin.LoadScene.cs.meta b/Runtime/Core/API/Pin.LoadScene.cs.meta new file mode 100644 index 0000000..fc450c8 --- /dev/null +++ b/Runtime/Core/API/Pin.LoadScene.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3698d761233c490a8f911cd7bd6cb785 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Core/API/Pin.SceneManagement.cs b/Runtime/Core/API/Pin.SceneManagement.cs index 29c79b1..e352161 100644 --- a/Runtime/Core/API/Pin.SceneManagement.cs +++ b/Runtime/Core/API/Pin.SceneManagement.cs @@ -65,7 +65,7 @@ internal static IDependencyContainer SetUpPersistent(PersistentCompositionRoot c } } - internal static void SetUpScene(SceneCompositionRoot compositionRoot) + internal static void SetUpScene(SceneCompositionRoot compositionRoot, ContextConfiguration config = null) { var compositionRootObject = compositionRoot.gameObject; var scene = compositionRootObject.scene; @@ -76,7 +76,7 @@ internal static void SetUpScene(SceneCompositionRoot compositionRoot) var persistentContainer = SetUpPersistent(compositionRoot.parent); // inject scene first - UnityStrategy.Inject(compositionRootObject, persistentContainer, null); + UnityStrategy.Inject(compositionRootObject, persistentContainer, config); var sceneContainer = compositionRootObject.GetOrAddContainerComponent(); @@ -115,4 +115,4 @@ internal static DependencyContainer GetSceneContainer(Scene scene) return container; } } -} +} \ No newline at end of file diff --git a/Runtime/Core/Common/DefaultInjectionStrategy.cs b/Runtime/Core/Common/DefaultInjectionStrategy.cs index 8d762ab..6cefdff 100644 --- a/Runtime/Core/Common/DefaultInjectionStrategy.cs +++ b/Runtime/Core/Common/DefaultInjectionStrategy.cs @@ -70,7 +70,7 @@ private void InjectProperties(ReflectionCache reflection, object obj, IDependenc { var value = container.Resolve(injectable.Type, injectable.IdGetter(obj)); - if (value == null) + if (value == null && !injectable.Optional) throw new InjectionException($"Type {injectable.Type} on {obj} cannot be resolved"); injectable.Setter(obj, value); diff --git a/Runtime/Core/Reflection/InjectAttribute.cs b/Runtime/Core/Reflection/InjectAttribute.cs index 4712c44..0722d97 100644 --- a/Runtime/Core/Reflection/InjectAttribute.cs +++ b/Runtime/Core/Reflection/InjectAttribute.cs @@ -13,10 +13,12 @@ public class InjectAttribute : PreserveAttribute { public readonly string Name; public readonly bool FromMember; + public readonly bool Optional = false; - public InjectAttribute() + public InjectAttribute(bool optional = false) { Name = null; + Optional = optional; } public InjectAttribute(string name, bool fromMember = false) diff --git a/Runtime/Core/Reflection/InjectOptionalAttribute.cs b/Runtime/Core/Reflection/InjectOptionalAttribute.cs new file mode 100644 index 0000000..3924d24 --- /dev/null +++ b/Runtime/Core/Reflection/InjectOptionalAttribute.cs @@ -0,0 +1,15 @@ +// PinInject, Maxwell Keonwoo Kang , 2022 + +using System; +using Cathei.PinInject; + +namespace Core.Reflection +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public class InjectOptionalAttribute : InjectAttribute + { + public InjectOptionalAttribute() : base(optional: true) + { + } + } +} \ No newline at end of file diff --git a/Runtime/Core/Reflection/InjectOptionalAttribute.cs.meta b/Runtime/Core/Reflection/InjectOptionalAttribute.cs.meta new file mode 100644 index 0000000..b60733c --- /dev/null +++ b/Runtime/Core/Reflection/InjectOptionalAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 347b8889b8244d319bd2e01a2de62f1d +timeCreated: 1698764791 \ No newline at end of file diff --git a/Runtime/Core/Reflection/ReflectionCache.cs b/Runtime/Core/Reflection/ReflectionCache.cs index 1b1da76..df85adb 100644 --- a/Runtime/Core/Reflection/ReflectionCache.cs +++ b/Runtime/Core/Reflection/ReflectionCache.cs @@ -63,7 +63,7 @@ private ReflectionCache(Type type) _injectables ??= new List(); _injectables.Add(new InjectableProperty( - prop.PropertyType, IdGetter(type, injectAttr), prop.SetValue)); + prop.PropertyType, IdGetter(type, injectAttr), prop.SetValue, injectAttr.Optional)); } if (resolveAttr != null) @@ -85,7 +85,7 @@ private ReflectionCache(Type type) { _injectables ??= new List(); _injectables.Add(new InjectableProperty( - field.FieldType, IdGetter(type, injectAttr), field.SetValue)); + field.FieldType, IdGetter(type, injectAttr), field.SetValue, injectAttr.Optional)); } if (resolveAttr != null) @@ -127,12 +127,14 @@ public struct InjectableProperty public readonly Type Type; public readonly Func IdGetter; public readonly Action Setter; + public readonly bool Optional; - public InjectableProperty(Type type, Func idGetter, Action setter) + public InjectableProperty(Type type, Func idGetter, Action setter, bool optional) { Type = type; IdGetter = idGetter; Setter = setter; + Optional = optional; } } diff --git a/Runtime/Core/Unity/SceneCompositionRoot.cs b/Runtime/Core/Unity/SceneCompositionRoot.cs index 3183606..72085a0 100644 --- a/Runtime/Core/Unity/SceneCompositionRoot.cs +++ b/Runtime/Core/Unity/SceneCompositionRoot.cs @@ -17,7 +17,7 @@ public class SceneCompositionRoot : MonoBehaviour, ICompositionRoot private void Awake() { - Pin.SetUpScene(this); + Pin.SetUpScene(this, Pin.sceneContextConfig); } private void OnDestroy()