/
vshmidt
/
masstransit
Обзор
Документация
Войти
/
vshmidt
/
masstransit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
src/MassTransit/Util/AssemblyTypeCache.cs
98 строк
4 KB
Chris Patterson
Added the ability to deploy the publish topology to the broker at startup, including any nested types when supported by the broker
25 авг 2022, 02:07
25 авг 2022, 02:07
5166f38
Код
Авторство
О чём код?
namespace MassTransit.Util { using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Scanning; /// <summary> /// Caches assemblies and assembly types to avoid repeated assembly scanning /// </summary> public static class AssemblyTypeCache { /// <summary> /// Remove all cached assemblies, essentially forcing a reload of any new assembly scans /// </summary> public static void Clear() { Cached.Assemblies.Clear(); } /// <summary> /// Use to assert that there were no failures in type scanning when trying to find the exported types /// from any Assembly /// </summary> public static void ThrowIfAnyTypeScanFailures() { IEnumerable<Exception> exceptions = FailedAssemblies().Select(x => x.Record.LoadException).ToList(); if (exceptions.Any()) throw new AggregateException(exceptions); } public static IEnumerable<AssemblyScanTypeInfo> FailedAssemblies() { Task<AssemblyScanTypeInfo>[] tasks = Cached.Assemblies.Select(x => x.Value).ToArray(); Task.WaitAll(tasks); return tasks.Where(x => x.Result.Record.LoadException != null).Select(x => x.Result); } public static Task<AssemblyScanTypeInfo> ForAssembly(Assembly assembly) { return Cached.Assemblies.GetOrAdd(assembly, assem => Task.Factory.StartNew(() => new AssemblyScanTypeInfo(assem))); } public static Task<TypeSet> FindTypes(IEnumerable<Assembly> assemblies, Func<Type, bool> filter = null) { Task<AssemblyScanTypeInfo>[] tasks = assemblies.Select(ForAssembly).ToArray(); return Task.Factory.ContinueWhenAll(tasks, assems => { return new TypeSet(assems.Select(x => x.Result).ToArray(), filter); }); } public static Task<IEnumerable<Type>> FindTypes(IEnumerable<Assembly> assemblies, TypeClassification classification, Func<Type, bool> filter = null) { var query = new TypeQuery(classification, filter); Task<IEnumerable<Type>>[] tasks = assemblies.Select(assem => ForAssembly(assem).ContinueWith(t => query.Find(t.Result))).ToArray(); return Task.Factory.ContinueWhenAll(tasks, results => results.SelectMany(x => x.Result)); } public static Task<IEnumerable<Type>> FindTypes(Assembly assembly, TypeClassification classification, Func<Type, bool> filter = null) { var query = new TypeQuery(classification, filter); return ForAssembly(assembly).ContinueWith(t => query.Find(t.Result)); } public static IEnumerable<Type> FindTypesInNamespace(Type type, Func<Type, bool> typeFilter, TypeClassification typeClassification) { if (type.Namespace == null) throw new ArgumentException("The type must have a valid namespace", nameof(type)); var dottedNamespace = type.Namespace + "."; bool Filter(Type candidate) { return typeFilter(candidate) && candidate.Namespace != null && (candidate.Namespace.StartsWith(dottedNamespace, StringComparison.OrdinalIgnoreCase) || candidate.Namespace.Equals(type.Namespace, StringComparison.OrdinalIgnoreCase)); } return FindTypes(type.Assembly, typeClassification, Filter).GetAwaiter().GetResult(); } static class Cached { internal static readonly ConcurrentDictionary<Assembly, Task<AssemblyScanTypeInfo>> Assemblies = new ConcurrentDictionary<Assembly, Task<AssemblyScanTypeInfo>>(); } } }