namespace ASC.Common.DependencyInjection { internal class AutofacComponent { public string Type { get; set; } public IEnumerable Services { get; set; } } internal class AutofacService { public string Type { get; set; } } public static class AutofacExtension { public static void Register(this ContainerBuilder builder, IConfiguration configuration, bool loadproducts = true, bool loadconsumers = true, params string[] intern) { var modules = new List<(bool, string)> { (true, "autofac.json") }; if (loadproducts) modules.Add((true, "autofac.products.json")); if (loadconsumers) modules.Add((true, "autofac.consumers.json")); if (intern != null) modules.AddRange(intern.Select(r => (false, r))); foreach (var p in modules) { var config = new ConfigurationBuilder(); if (p.Item1) config.SetBasePath(configuration["pathToConf"]); config.AddJsonFile(p.Item2); var root = config.Build(); var module = new ConfigurationModule(root); builder.RegisterModule(module); } return; } public static List FindAndLoad(IConfiguration configuration, string currentDir, string section = "autofac.products.json") { var config = new ConfigurationBuilder(); config.SetBasePath(configuration["pathToConf"]); config.AddJsonFile(section); var root = config.Build(); var sectionSettings = root.GetSection("components"); if (sectionSettings == null) return new List(); var folder = configuration["core:products:folder"]; var subfolder = configuration["core:products:subfolder"]; string productsDir; if (!Path.IsPathRooted(folder)) { if (currentDir.EndsWith(CrossPlatform.PathCombine(Path.GetFileName(folder), Assembly.GetEntryAssembly().GetName().Name, subfolder))) productsDir = Path.GetFullPath(CrossPlatform.PathCombine("..", "..")); else productsDir = Path.GetFullPath(CrossPlatform.PathCombine(currentDir, folder)); } else productsDir = folder; var cs = new List(); sectionSettings.Bind(cs); var types = new List(); foreach (var component in cs) { try { LoadAssembly(component.Type); types.Add(component.Type); } catch (System.Exception) { //TODO } } return types; void LoadAssembly(string type) { var dll = type.Substring(type.IndexOf(",") + 1).Trim(); var path = GetFullPath(dll); if (!string.IsNullOrEmpty(path)) AssemblyLoadContext.Default.Resolving += new Resolver(path).Resolving; } string GetFullPath(string n) { var productPath = CrossPlatform.PathCombine(productsDir, n, subfolder); return GetPath(CrossPlatform.PathCombine(productPath, "bin"), n, SearchOption.AllDirectories) ?? GetPath(productPath, n, SearchOption.TopDirectoryOnly); } static string GetPath(string dirPath, string dll, SearchOption searchOption) { if (!Directory.Exists(dirPath)) return null; return Directory.GetFiles(dirPath, $"{dll}.dll", searchOption).FirstOrDefault(); } } } class Resolver { private readonly string _resolvePath; public Resolver(string assemblyPath) => _resolvePath = assemblyPath; public Assembly Resolving(AssemblyLoadContext context, AssemblyName assemblyName) { var path = CrossPlatform.PathCombine(Path.GetDirectoryName(_resolvePath), $"{assemblyName.Name}.dll"); if (!File.Exists(path)) return null; return context.LoadFromAssemblyPath(path); } } }