using System.Reflection;
using System.Security.AccessControl;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Module = Autofac.Module;

namespace PVDEMCS.Common.DI;

/// <summary>
/// 自定义扩展 Autofac 方法
/// </summary>
public static class AutoFacBuilderExtensions
{
    /// <summary>
    /// 添加Autofac扩展
    /// </summary>
    /// <param name="builder"></param>
    public static void AddAutofacExt(this WebApplicationBuilder builder)
    {
        // 通过工厂替换，把Autofac整合进来
        builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
                    .ConfigureContainer<ContainerBuilder>(
                        build =>
                        {
                            build.RegisterModule(new AutoFacManager());
                        });
    }
}

public class AutoFacManager : Module
{
    // 重写 Autofac 管道 Load方法, 在这里注入
    protected override void Load(ContainerBuilder builder)
    {
        /* 2、获取接口类型
           * 通过IDependency标记需要依赖注入的接口
           * 注册所有实现了IDependency接口的类型
           */
        Type baseType = typeof(IDependency);
        #region 依赖注入
        /* 3、获取所有程序集
                     * 当CLR COM服务器初始化时，它会创建一个AppDomain。 AppDomain是一组程序集的逻辑容器
                     */
        var assemblies = AppDomain.CurrentDomain.GetAssemblies();//这种写法AppDomain重新启动后会丢失程序集
                                                                 //var assemblies = Assembly.GetAssembly(baseType);
        /* 4、自动注册接口
         * 筛选出对应条件的接口
         * IsAssignableFrom：返回true的条件：是否直接或间接实现了IDependency
         * IsAbstract：是否为抽象类
         * AsImplementedInterfaces：以接口的形式注册
         * InstancePerLifetimeScope：同一个Lifetime生成的对象是同一个实例
         */
        builder.RegisterAssemblyTypes(assemblies).Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract).AsImplementedInterfaces().SingleInstance();

        #endregion

        base.Load(builder);
    }
}