.NET实现简单的IOC容器
准备接口及实现类
public interface IHeadphone
{
}
public interface IMicrophone
{
}
public interface IPower
{
}
public class Headphone : IHeadphone
{
public Headphone(IPower power)
{
Console.WriteLine($"{this.GetType().Name}被构造...");
}
}
public class Microphone : IMicrophone
{
public Microphone()
{
Console.WriteLine($"{this.GetType().Name}被构造..");
}
}
public class Power : IPower
{
[Selector]
public Power(IMicrophone microphone)
{
Console.WriteLine($"{this.GetType().Name}被构造了");
}
public Power()
{
Console.WriteLine($"{this.GetType().Name}被构造了");
}
}
定义ICustomServiceCollection接口
public interface ICustomServiceCollection
{
public void AddTransient<TFrom, TTo>() where TTo : TFrom;
public TFrom GetService<TFrom>();
}
接口的实现类CustomServiceCollection
public class CustomServiceCollection : ICustomServiceCollection
{
//定义字典用于存储抽象和实现的键值对
private static Dictionary<string, Type> MapDictionary =
new Dictionary<string, Type>();
/// <summary>
/// 注册抽象和细节的关系
/// </summary>
/// <typeparam name="TFrom">抽象:接口</typeparam>
/// <typeparam name="TTo">实现</typeparam>
/// <exception cref="NotImplementedException"></exception>
public void AddTransient<TFrom, TTo>() where TTo:TFrom
{
string tFromName= typeof(TFrom).FullName;
MapDictionary.Add(tFromName, typeof(TTo));
}
/// <summary>
/// 获取实例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <returns></returns>
public TFrom GetService<TFrom>()
{
Type type= typeof(TFrom);
return (TFrom)CreateService(type);
}
public object CreateService(Type type)
{
string tFromName = type.FullName;
//如果参数没有注册过或者是普通的int、string等类型,则应该抛出异常
if (!MapDictionary.ContainsKey(tFromName))
{
throw new ArgumentException("Wrong");
}
//通过字典获取之前注册的实现类型
Type Totype = MapDictionary[tFromName];
//定义一个空的构造函数类型
ConstructorInfo ctor = null;
//获取实现类型的所有构造函数
ConstructorInfo[] ctorArgs = Totype.GetConstructors();
//获取所有标记Selector特性的构造函数,Selector用来标记想要使用的的构造函数
List<ConstructorInfo> constructorInfos = ctorArgs
.Where(m => m
.IsDefined(typeof(SelectorAttribute), true))
.ToList();
//如果为空能获取到,则使用第一个
if (constructorInfos != null && constructorInfos.Count > 0)
{
ctor = constructorInfos.First();
}
else//否则使用参数最多的构造函数
{
ctor = ctorArgs.OrderByDescending(m => m.GetParameters().Count()).First();
}
//难点在于,构造函数的参数可能是一个类,可能还会有构造函数参数等问题,如此循环。。。
//因此使用递归
List<object> objList = new List<object>();
foreach (var para in ctor.GetParameters())
{
object paraObj = CreateService(para.ParameterType);
objList.Add(paraObj);
}
return Activator.CreateInstance(Totype, objList.ToArray());
}
}
在Program类中使用
//自定义IOC
ICustomServiceCollection customServiceCollection = new CustomServiceCollection();
customServiceCollection.AddTransient<IMicrophone, Microphone>();
customServiceCollection.AddTransient<IPower, Power>();
customServiceCollection.AddTransient<IHeadphone, Headphone>();
IMicrophone microphone1 = customServiceCollection.GetService<IMicrophone>();
IPower power1 = customServiceCollection.GetService<IPower>();
IHeadphone headphone1 = customServiceCollection.GetService<IHeadphone>();
// 原版IOC
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IMicrophone, Microphone>();
builder.Services.AddTransient<IPower, Power>();
builder.Services.AddTransient<IHeadphone,Headphone>();
var app = builder.Build();
IMicrophone? microphone = app.Services.GetService<IMicrophone>();
IHeadphone? headphone = app.Services.GetService<IHeadphone>();
IPower? power=app.Services.GetService<IPower>();