101 lines
2.9 KiB
C#
101 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Linq;
|
|
|
|
namespace CommonConsole
|
|
{
|
|
public class Program
|
|
{
|
|
|
|
public class ServiceProvider : IServiceProvider
|
|
{
|
|
private static readonly ServiceProvider serviceProvider
|
|
= new ServiceProvider();
|
|
private static readonly ConcurrentDictionary<Type, object> services
|
|
= new ConcurrentDictionary<Type, object>();
|
|
|
|
private ServiceProvider()
|
|
{
|
|
|
|
}
|
|
|
|
public object GetService(Type serviceType)
|
|
{
|
|
return services.GetOrAdd(serviceType, default(object));
|
|
}
|
|
|
|
public static T GetService<T>()
|
|
{
|
|
var serviceType = typeof(T);
|
|
var serviceInstance = default(T);
|
|
|
|
if (serviceProvider.GetService(serviceType) is T existingInstance)
|
|
{
|
|
serviceInstance = existingInstance;
|
|
}
|
|
else if (CreateInstance(serviceType) is T newInstance)
|
|
{
|
|
serviceInstance = newInstance;
|
|
}
|
|
|
|
return serviceInstance;
|
|
}
|
|
|
|
private static object CreateInstance(Type instanceType)
|
|
{
|
|
var instance = default(object);
|
|
var constructor = instanceType
|
|
.GetConstructors()
|
|
.OrderBy(x => x.GetParameters().Length)
|
|
.FirstOrDefault();
|
|
|
|
if (constructor != null)
|
|
{
|
|
var parameters = constructor.GetParameters();
|
|
var parametersLength = parameters.Length;
|
|
var createParameters = new object[parametersLength];
|
|
|
|
for (int i = 0; i < parametersLength; i++)
|
|
{
|
|
var parameterType = parameters[i].ParameterType;
|
|
var parameter = serviceProvider.GetService(parameterType);
|
|
|
|
if (parameter is null)
|
|
{
|
|
parameter = CreateInstance(parameterType);
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
instance = constructor.Invoke(createParameters);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
}
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
}
|
|
|
|
public class TestInstance
|
|
{
|
|
public TestInstance(TestValue value)
|
|
{
|
|
Console.WriteLine("Created");
|
|
}
|
|
}
|
|
|
|
public class TestValue
|
|
{
|
|
|
|
}
|
|
|
|
public static void Main()
|
|
{
|
|
var service = ServiceProvider.GetService<TestInstance>();
|
|
}
|
|
}
|
|
} |