using Serein.Library.Http;
using SqlSugar;
using System.Collections.Concurrent;
using System.Reflection;
namespace Serein.Library.IOC
{
public interface IServiceContainer
{
///
/// 获取或创建类型的实例(不注入依赖项)
///
object GetOrCreateServiceInstance(Type serviceType, params object[] parameters);
T CreateServiceInstance(params object[] parameters);
IServiceContainer Reset(); // 清空
IServiceContainer Register(Type type, params object[] parameters);
IServiceContainer Register(params object[] parameters);
IServiceContainer Register(params object[] parameters) where TImplementation : TService;
T Get();
object Get(Type type);
///
/// 创建目标类型的对象, 并注入依赖项
///
object? Instantiate(Type type, params object[] parameters);
IServiceContainer Build();
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
IServiceContainer Run(Action action);
}
public class ServiceContainer : IServiceContainer
{
private readonly ConcurrentDictionary _dependencies;
private readonly ConcurrentDictionary _typeMappings;
private readonly List _waitingForInstantiation;
public ServiceContainer()
{
_dependencies = new ConcurrentDictionary
{
[typeof(IServiceContainer).FullName] = this
};
_typeMappings = new ConcurrentDictionary();
_waitingForInstantiation = [];
}
public object GetOrCreateServiceInstance(Type type, params object[] parameters)
{
Register(type);
object instance;
if (_dependencies.ContainsKey(type.FullName))
{
instance = _dependencies[type.FullName];
}
else
{
instance = Activator.CreateInstance(type);
_dependencies[type.FullName] = instance;
}
return instance;
}
public T CreateServiceInstance(params object[] parameters)
{
return (T)GetOrCreateServiceInstance(typeof(T), parameters);
}
public IServiceContainer Reset()
{
foreach(var instancei in _dependencies.Values)
{
if (typeof(IDisposable).IsAssignableFrom(instancei.GetType()) && instancei is IDisposable disposable)
{
disposable.Dispose();
}
}
_dependencies.Clear();
_waitingForInstantiation.Clear();
//_typeMappings.Clear();
return this;
}
public IServiceContainer Register(Type type, params object[] parameters)
{
if (!_typeMappings.ContainsKey(type.FullName))
{
_typeMappings[type.FullName] = type;
}
return this;
}
public IServiceContainer Register(params object[] parameters)
{
Register(typeof(T), parameters);
return this;
}
public IServiceContainer Register(params object[] parameters)
where TImplementation : TService
{
_typeMappings[typeof(TService).FullName!] = typeof(TImplementation);
return this;
}
public object Get(Type type)
{
if (!_dependencies.TryGetValue(type.FullName, out object value))
{
Register(type);
value = Instantiate(type);
InjectDependencies(type);
}
return value;
}
public T Get()
{
if(!_dependencies.TryGetValue(typeof(T).FullName, out object value))
{
Register();
value = Instantiate(typeof(T));
}
return (T)value;
//throw new InvalidOperationException("目标类型未创建实例");
}
public IServiceContainer Build()
{
foreach (var type in _typeMappings.Values)
{
if(!_dependencies.ContainsKey(type.FullName))
{
_dependencies[type.FullName] = Activator.CreateInstance(type);
}
}
foreach (var instance in _dependencies.Values)
{
InjectDependencies(instance); // 替换占位符
}
//var instance = Instantiate(item.Value);
TryInstantiateWaitingDependencies();
return this;
}
public object? Instantiate(Type controllerType, params object[] parameters)
{
var instance = Activator.CreateInstance(controllerType, parameters);
if(instance != null)
{
InjectDependencies(instance);
}
return instance;
}
private void InjectDependencies(object instance)
{
var properties = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanWrite && p.GetCustomAttribute() != null);
foreach (var property in properties)
{
var propertyType = property.PropertyType;
if (_dependencies.TryGetValue(propertyType.FullName, out var dependencyInstance))
{
property.SetValue(instance, dependencyInstance);
}
}
}
private void TryInstantiateWaitingDependencies()
{
foreach (var waitingType in _waitingForInstantiation.ToList())
{
if (_typeMappings.TryGetValue(waitingType.FullName!, out var implementationType))
{
var instance = Instantiate(implementationType);
if (instance != null)
{
_dependencies[waitingType.FullName] = instance;
_waitingForInstantiation.Remove(waitingType);
}
}
}
}
#region run()
public IServiceContainer Run(Action action)
{
var service = Get();
if (service != null)
{
action(service);
}
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
action(service1, service2);
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
var service3 = Get();
action(service1, service2, service3);
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
var service3 = Get();
var service4 = Get();
action(service1, service2, service3, service4);
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
var service3 = Get();
var service4 = Get();
var service5 = Get();
action(service1, service2, service3, service4, service5);
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
var service3 = Get();
var service4 = Get();
var service5 = Get();
var service6 = Get();
action(service1, service2, service3, service4, service5, service6);
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
var service3 = Get();
var service4 = Get();
var service5 = Get();
var service6 = Get();
var service7 = Get();
action(service1, service2, service3, service4, service5, service6, service7);
return this;
}
public IServiceContainer Run(Action action)
{
var service1 = Get();
var service2 = Get();
var service3 = Get();
var service4 = Get();
var service5 = Get();
var service6 = Get();
var service7 = Get();
var service8 = Get();
action(service1, service2, service3, service4, service5, service6, service7, service8);
return this;
}
#endregion
}
/* public interface IServiceContainer
{
ServiceContainer Register(params object[] parameters);
ServiceContainer Register(params object[] parameters) where TImplementation : TService;
TService Resolve();
void Get(Action action);
object Instantiate(Type type, params object[] parameters);
}
public class ServiceContainer : IServiceContainer
{
private readonly Dictionary _dependencies;
public ServiceContainer()
{
_dependencies = new Dictionary
{
[typeof(IServiceContainer)] = this
};
}
public void Get(Action action)
{
var service = Resolve();
action(service);
}
public ServiceContainer Register(params object[] parameters)
{
var instance = Instantiate(typeof(T), parameters);
_dependencies[typeof(T)] = instance;
return this;
}
public ServiceContainer Register(params object[] parameters)
where TImplementation : TService
{
_dependencies[typeof(TService)] = Instantiate(typeof(TImplementation), parameters);
return this;
}
public TService Resolve()
{
return (TService)_dependencies[typeof(TService)];
}
public object Instantiate(Type controllerType, params object[] parameters)
{
var constructors = controllerType.GetConstructors(); // 获取控制器的所有构造函数
// 查找具有最多参数的构造函数
var constructor = constructors.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
if (constructor != null)
{
if (parameters.Length > 0)
{
return Activator.CreateInstance(controllerType, parameters);
}
else {
var tmpParameters = constructor.GetParameters();
var dependencyInstances = new List