using System; using System.Collections.Generic; using System.Linq; using System.Threading; using Microsoft.Extensions.DependencyInjection; namespace BITKit.Entities { public class Entity : IEntity, IDisposable { private class EntityServiceProvider : IServiceProvider { public ServiceProvider ServiceProvider; public readonly List Services = new(); public object GetService(Type serviceType) { var value = ServiceProvider.GetService(serviceType); if (value != null) { Services.TryAdd(value); } return value; } } public Entity() { ServiceCollection.AddSingleton(this); } public void WaitForInitializationComplete() { throw new NotImplementedException(); } public int Id { get; set; } = Guid.NewGuid().GetHashCode(); public CancellationToken CancellationToken => _cancellationTokenSource.Token; private readonly CancellationTokenSource _cancellationTokenSource = new(); public IServiceProvider ServiceProvider { get { if (_serviceProvider is not null) { return _serviceProvider; } var value = new EntityServiceProvider() { ServiceProvider = ServiceCollection.BuildServiceProvider() }; _serviceProvider = value; return _serviceProvider; } } public IServiceCollection ServiceCollection { get; } = new ServiceCollection(); private EntityServiceProvider _serviceProvider; public object[] GetServices()=> _serviceProvider.Services.ToArray(); public void Inject(object obj) { foreach (var fieldInfo in obj.GetType().GetFields(ReflectionHelper.Flags)) { if (Attribute.IsDefined(fieldInfo, typeof(InjectAttribute))) { fieldInfo.SetValue(obj, ServiceProvider.GetService(fieldInfo.FieldType)); } } } public void Dispose() { _cancellationTokenSource.Cancel(); _serviceProvider.ServiceProvider.Dispose(); foreach (var x in GetServices().OfType()) { x.Dispose(); } } } }