#if UNITY_5_3_OR_NEWER using System; using System.Collections; using System.Collections.Generic; using System.Threading; using Microsoft.Extensions.DependencyInjection; using UnityEngine; using Object = UnityEngine.Object; namespace BITKit.Entities { [DisallowMultipleComponent] [DefaultExecutionOrder(-1)] public class UnityEntity : MonoBehaviour,IEntity { private IEntitiesService _entitiesService; private IEntity _entity; private void Start() { _entitiesService = BITApp.ServiceProvider.GetRequiredService(); if (_entitiesService.Entities.ContainsKey(gameObject.GetInstanceID())) return; var entity = new Entity() { Id = gameObject.GetInstanceID(), CancellationToken = destroyCancellationToken }; var idComponent = new IdComponent() { Id = entity.Id, Name = gameObject.name, }; entity.ServiceCollection.AddSingleton(idComponent); foreach (var component in GetComponents()) { var type = component.GetType(); foreach (var x in type.GetInterfaces()) { entity.ServiceCollection.AddSingleton(x, component); } while (type is not null) { var baseType = type.BaseType; try { switch (baseType) { case null: case not null when baseType == typeof(object): case not null when baseType == typeof(Object): case not null when baseType == typeof(MonoBehaviour): case not null when baseType == typeof(Behaviour): case not null when baseType == typeof(Component): case not null when baseType == typeof(Component): throw new OperationCanceledException(); } } catch (OperationCanceledException) { break; } entity.ServiceCollection.AddSingleton(baseType, component); type = type.BaseType; } } entity.ServiceCollection.AddSingleton(gameObject); entity.ServiceCollection.AddSingleton(transform); destroyCancellationToken.Register(Dispose); _entity = entity; _entitiesService.Register(entity); } private void Dispose() { _entitiesService?.UnRegister(_entity); } public int Id => _entity.Id; public CancellationToken CancellationToken => _entity.CancellationToken; public IServiceProvider ServiceProvider => _entity.ServiceProvider; public IServiceCollection ServiceCollection => _entity.ServiceCollection; public void Inject(object obj) { _entity.Inject(obj); } } } #endif