BlackLambert_unity-di-package/Runtime/Scripts/Core/Installer/AppContextInstaller.cs
using UnityEngine;
using UnityEngine.UI;

namespace SBaier.DI
{
    public class AppContextInstaller : Installer
    {
        private DIContext _diContext;
        private GameObject _contextObject;

        public AppContextInstaller(DIContext dIContext, GameObject contextObject)
        {
            _diContext = dIContext;
            _contextObject = contextObject;
        }

        public void InstallBindings(Binder binder)
        {
            binder.BindToNewSelf<GameObjectInjector>();
            
            binder.BindToNewSelf<GameObjectContextsReseter>();
            
            binder.BindToNewSelf<SceneInjector>();
            
            binder.BindInstance(_diContext)
                .WithoutInjection();
            
            binder.BindToNewSelf<DIInstanceFactory>();
            
            binder.BindToSelf<DIContainers>()
                .FromFactory();
            
            binder.Bind<Factory<DIContainers>>()
                .ToNew<DIContainersFactory>();
            
            binder.BindToNewSelf<SceneContextProvider>()
                .AsSingle();
            
            binder.Bind<Factory<ChildDIContext, Resolver>>()
                .ToNew<ChildDIContextFactory>();
            
            binder.BindToSelf<MonoPoolCache>()
                .FromMethod(CreatePoolCache)
                .AsSingle();

            binder.Bind<GameObjectLifeCycleActionCaller<Cleanable>>()
                .And<GameObjectCleaner>()
                .ToNew<GameObjectCleaner>();
            
            binder.Bind<GameObjectLifeCycleActionCaller<Initializable>>()
                .And<GameObjectInitializer>()
                .ToNew<GameObjectInitializer>();
            
            binder.BindToNewSelf<SceneObjectsLifeCycleActionCaller<Cleanable>>();
            
            binder.BindToNewSelf<SceneObjectsLifeCycleActionCaller<Initializable>>();
            
            binder.Bind<ObjectActivator>()
                .ToNew<BasicObjectActivator>();
            
            new BindingValidationInstaller()
                .InstallBindings(binder);
            
            new QuitDetectorInstaller(_contextObject)
                .InstallBindings(binder);
        }

		private MonoPoolCache CreatePoolCache()
		{
            GameObject cacheObject = new GameObject(nameof(MonoPoolCache));
            GameObject uiCacheObject = new GameObject("UI Cache");
            Canvas canvas = uiCacheObject.AddComponent<Canvas>();
            uiCacheObject.AddComponent<CanvasScaler>();
            canvas.renderMode = RenderMode.ScreenSpaceOverlay;
            uiCacheObject.transform.SetParent(cacheObject.transform);
            cacheObject.transform.SetParent(_contextObject.transform);
            return cacheObject.AddComponent<MonoPoolCache>();
        }
	}
}
