.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>();

 

posted @ 2022-11-23 10:03  守护月亮的星星  阅读(144)  评论(0)    收藏  举报