面试官:如何实现一个简易的依赖注入(DI)框架

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

// 服务生命周期
public enum ServiceLifetime
{
    Transient,  // 每次请求都创建新实例
    Singleton   // 全局单例
}

// 服务描述符
public class ServiceDescriptor
{
    public Type ServiceType { get; set; }
    public Type ImplementationType { get; set; }
    public ServiceLifetime Lifetime { get; set; }
    public object Instance { get; set; } // 用于存储 Singleton 实例
}

// 简易 DI 容器
public class SimpleServiceCollection
{
    // 核心:使用 Dictionary 存储服务注册信息
    private readonly Dictionary<Type, ServiceDescriptor> _services = new();

    // 注册瞬态服务
    public void AddTransient<TService, TImplementation>() 
        where TImplementation : TService
    {
        _services[typeof(TService)] = new ServiceDescriptor
        {
            ServiceType = typeof(TService),
            ImplementationType = typeof(TImplementation),
            Lifetime = ServiceLifetime.Transient
        };
    }

    // 注册单例服务
    public void AddSingleton<TService, TImplementation>() 
        where TImplementation : TService
    {
        _services[typeof(TService)] = new ServiceDescriptor
        {
            ServiceType = typeof(TService),
            ImplementationType = typeof(TImplementation),
            Lifetime = ServiceLifetime.Singleton
        };
    }

    // 构建服务提供者
    public SimpleServiceProvider BuildServiceProvider()
    {
        return new SimpleServiceProvider(_services);
    }
}

// 服务提供者
public class SimpleServiceProvider
{
    private readonly Dictionary<Type, ServiceDescriptor> _services;

    public SimpleServiceProvider(Dictionary<Type, ServiceDescriptor> services)
    {
        _services = services;
    }

    // 获取服务实例(核心方法)
    public T GetService<T>()
    {
        return (T)GetService(typeof(T));
    }

    public object GetService(Type serviceType)
    {
        if (!_services.ContainsKey(serviceType))
        {
            throw new Exception($"服务 {serviceType.Name} 未注册");
        }

        var descriptor = _services[serviceType];

        // 如果是单例且已创建,直接返回
        if (descriptor.Lifetime == ServiceLifetime.Singleton && descriptor.Instance != null)
        {
            return descriptor.Instance;
        }

        // 创建实例
        var instance = CreateInstance(descriptor.ImplementationType);

        // 如果是单例,保存实例
        if (descriptor.Lifetime == ServiceLifetime.Singleton)
        {
            descriptor.Instance = instance;
        }

        return instance;
    }

    // 创建实例(使用反射 + 递归解析依赖)
    private object CreateInstance(Type implementationType)
    {
        // 获取构造函数(这里简化为选择第一个公共构造函数)
        var constructors = implementationType.GetConstructors();
        if (constructors.Length == 0)
        {
            throw new Exception($"类型 {implementationType.Name} 没有公共构造函数");
        }

        var constructor = constructors[0];

        // 获取构造函数参数
        var parameters = constructor.GetParameters();
        var parameterInstances = new object[parameters.Length];

        // 递归解析每个依赖参数
        for (int i = 0; i < parameters.Length; i++)
        {
            var parameterType = parameters[i].ParameterType;
            parameterInstances[i] = GetService(parameterType);
        }

        // 使用反射创建实例
        return Activator.CreateInstance(implementationType, parameterInstances);
    }
}

// ============= 使用示例 =============

// 定义服务接口和实现
public interface ILogger
{
    void Log(string message);
}

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

public interface IUserService
{
    void CreateUser(string name);
}

public class UserService : IUserService
{
    private readonly ILogger _logger;

    // 构造函数注入依赖
    public UserService(ILogger logger)
    {
        _logger = logger;
    }

    public void CreateUser(string name)
    {
        _logger.Log($"创建用户: {name}");
    }
}

// 测试代码
public class Program
{
    public static void Main()
    {
        // 1. 创建容器并注册服务
        var services = new SimpleServiceCollection();
        services.AddSingleton<ILogger, ConsoleLogger>();
        services.AddTransient<IUserService, UserService>();

        // 2. 构建服务提供者
        var serviceProvider = services.BuildServiceProvider();

        // 3. 获取服务并使用
        var userService = serviceProvider.GetService<IUserService>();
        userService.CreateUser("张三");

        // 4. 验证单例行为
        var logger1 = serviceProvider.GetService<ILogger>();
        var logger2 = serviceProvider.GetService<ILogger>();
        Console.WriteLine($"Logger 是否为同一实例: {ReferenceEquals(logger1, logger2)}");

        // 5. 验证瞬态行为
        var userService1 = serviceProvider.GetService<IUserService>();
        var userService2 = serviceProvider.GetService<IUserService>();
        Console.WriteLine($"UserService 是否为同一实例: {ReferenceEquals(userService1, userService2)}");
    }
}
posted @ 2025-11-21 09:46  talentzemin  阅读(4)  评论(0)    收藏  举报