Prism 本身并不强制使用特定的 IoC 容器(它支持 Unity、DryIoc、Autofac、Microsoft.Extensions.DependencyInjection 等),但其核心思想是通过容器管理对象生命周期、自动解析依赖。

下面逐步设计并实现一个简化版的 IoC 容器,具备以下功能:

  • 注册类型(支持瞬态、单例)
  • 解析服务(支持构造函数注入)
  • 自动解析依赖链
  • 基础生命周期管理

🧱 第一步:明确核心概念

1. 服务注册表(Service Registry)

存储“服务类型 → 实现类型/工厂”的映射。

2. 生命周期管理

  • Transient:每次解析都创建新实例
  • Singleton:整个容器中只创建一次,后续返回同一实例

3. 依赖解析器(Resolver)

根据类型,递归解析其构造函数参数所需的依赖。


🛠 第二步:定义接口和枚举

public enum Lifetime
{
    Transient,
    Singleton
}

public interface IContainer
{
    void Register<TService, TImplementation>(Lifetime lifetime = Lifetime.Transient)
        where TImplementation : class, TService
        where TService : class;

    void Register<TService>(Lifetime lifetime = Lifetime.Transient)
        where TService : class;

    T Resolve<T>() where T : class;
    object Resolve(Type serviceType);
}

📦 第三步:实现注册项(Registration)

public class ServiceRegistration
{
    public Type ServiceType { get; }
    public Type ImplementationType { get; }
    public Lifetime Lifetime { get; }

    public ServiceRegistration(Type serviceType, Type implementationType, Lifetime lifetime)
    {
        ServiceType = serviceType;
        ImplementationType = implementationType;
        Lifetime = lifetime;
    }
}

🧠 第四步:实现容器核心逻辑

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

public class SimpleContainer : IContainer
{
    private readonly Dictionary<Type, ServiceRegistration> _registrations = new();
    private readonly Dictionary<Type, object> _singletonInstances = new();

    public void Register<TService, TImplementation>(Lifetime lifetime = Lifetime.Transient)
        where TImplementation : class, TService
        where TService : class
    {
        var registration = new ServiceRegistration(typeof(TService), typeof(TImplementation), lifetime);
        _registrations[typeof(TService)] = registration;
    }

    public void Register<TService>(Lifetime lifetime = Lifetime.Transient)
        where TService : class
    {
        // 自绑定:服务即实现
        Register<TService, TService>(lifetime);
    }

    public T Resolve<T>() where T : class => (T)Resolve(typeof(T));

    public object Resolve(Type serviceType)
    {
        if (!_registrations.TryGetValue(serviceType, out var registration))
            throw new InvalidOperationException($"Service {serviceType} is not registered.");

        if (registration.Lifetime == Lifetime.Singleton)
        {
            if (_singletonInstances.TryGetValue(serviceType, out var existing))
                return existing;

            var instance = CreateInstance(registration.ImplementationType);
            _singletonInstances[serviceType] = instance;
            return instance;
        }

        return CreateInstance(registration.ImplementationType);
    }

    private object CreateInstance(Type type)
    {
        // 获取最匹配的公共构造函数(这里简化:选参数最多的)
        var constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
        if (constructors.Length == 0)
            throw new InvalidOperationException($"No public constructor found for {type}.");

        var constructor = constructors.OrderByDescending(c => c.GetParameters().Length).First();
        var parameters = constructor.GetParameters()
            .Select(p => Resolve(p.ParameterType))
            .ToArray();

        return constructor.Invoke(parameters);
    }
}

✅ 第五步:测试用例

// 示例服务
public interface ILogger
{
    void Log(string message);
}

public class ConsoleLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"LOG: {message}");
}

public class EmailService
{
    private readonly ILogger _logger;

    public EmailService(ILogger logger)
    {
        _logger = logger;
    }

    public void Send(string to, string msg)
    {
        _logger.Log($"Sending email to {to}: {msg}");
    }
}

// 使用容器
class Program
{
    static void Main()
    {
        var container = new SimpleContainer();

        container.Register<ILogger, ConsoleLogger>(Lifetime.Singleton);
        container.Register<EmailService>(Lifetime.Transient);

        var email1 = container.Resolve<EmailService>();
        var email2 = container.Resolve<EmailService>();

        email1.Send("alice@example.com", "Hello");
        email2.Send("bob@example.com", "Hi");

        // 验证是否是同一个 logger(单例)
        var logger1 = container.Resolve<ILogger>();
        var logger2 = container.Resolve<ILogger>();
        Console.WriteLine(ReferenceEquals(logger1, logger2)); // True
    }
}

🔧 第六步:可扩展方向(进阶)

你的简易容器已经能工作了!接下来可以考虑增强:

功能实现思路
工厂注册支持 Register<T>(factory: () => new T())
命名注册支持多个同类型不同实现(如 Register<ILogger>("file")
属性注入CreateInstance 后反射设置属性
泛型支持处理 IRepository<T>Repository<T>
作用域生命周期(Scoped)引入 CreateScope() 方法
自动批量注册扫描程序集,按约定注册

📌 总结:实现步骤回顾

  1. 定义接口IContainer + 生命周期枚举
  2. 设计注册模型ServiceRegistration
  3. 实现注册方法:支持泛型、自绑定
  4. 实现解析逻辑:递归解析构造函数依赖
  5. 管理单例缓存
  6. 测试验证
  7. 逐步扩展

💡 虽然这个容器很基础,但它体现了 IoC 的核心思想:解耦对象创建与使用,由容器负责依赖组装


更多推荐