net6通过反射注册装配autofac


首先创建2个用于反射的标记 ServiceName是用来做多租户标记的

 public class InjectAttribute : Attribute
    {

        public string ServiceName { get; set; }

        public InjectAttribute(string serviceName)
        {
            ServiceName = serviceName;
        }

        public InjectAttribute()
        {
            ServiceName = "";
        }
    }

 public class DenpendencyAttribute : Attribute
    {
    }

 

创建Autofac装配初始化的类

public static class AutofacAutoRegisterInit
    {
        public static void Init(ContainerBuilder builder, params Assembly[] assembliesWithServices)
        {
            Dictionary<Type, List<Type>> diDic = new Dictionary<Type, List<Type>>();

            foreach (Assembly assembly in assembliesWithServices)
            {
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.GetCustomAttribute<DenpendencyAttribute>() != null)
                    {
                        if (!diDic.ContainsKey(type))
                        {
                            diDic.Add(type, new List<Type>());
                        }
                    }

                    if (type.GetCustomAttribute<InjectAttribute>() != null)
                    {
                        foreach (Type ImplementedInterface in type.GetTypeInfo().ImplementedInterfaces)
                        {
                            if (diDic.ContainsKey(ImplementedInterface))
                            {
                                diDic[ImplementedInterface].Add(type);
                            }
                            else
                            {
                                diDic.Add(ImplementedInterface, new List<Type>() { type });
                            }
                        }
                    }
                }
            }

            foreach (Type denpendencyType in diDic.Keys)
            {
                foreach (Type injectType in diDic[denpendencyType])
                {
                    string serviceName = injectType.GetCustomAttribute<InjectAttribute>()!.ServiceName;
                    builder.RegisterType(injectType).Keyed(serviceName, denpendencyType).As(denpendencyType);
                }
                builder.Register<Func<string, object>>(c =>
                {
                    var ic = c.Resolve<IComponentContext>();
                    return named => ic.ResolveKeyed(named, denpendencyType);
                });
            }
        }
    }

修改启动文件内容 必须使用DependencyContext.Default来获取程序集,不能通过运行项目路径加载,否则会导致程序集不匹配。

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory(autofacBuilder =>
{
    var libs = DependencyContext.Default.CompileLibraries.Where(u => u.Name.Contains("APITemplate"));
    List<Assembly> loadAssembly = new List<Assembly>();
    foreach (var lib in libs)
    {
        loadAssembly.Add(AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name)));
    }
    AutofacAutoRegisterInit.Init(autofacBuilder, loadAssembly.ToArray());
}));

如何使用?

单一实现和正常的构造函数注入方式一样

多租户使用以下方式Test参数就是Inject中的Servicename

private readonly Func<string,IApolloApplicationService> apolloApplicationService;

        public ApolloController(Func<string, IApolloApplicationService> apolloApplicationService)
        {
            this.apolloApplicationService = apolloApplicationService;
        }

        [HttpGet]
        public ActionResult Get([FromRoute] string key)
        {
            var value = apolloApplicationService("Test").GetValue(key);
            return Ok(value);
        }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM