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