public DFrameWorkloadTypeInfo(Type workloadType, string name, IServiceProviderIsService isService) { this.isService = isService; this.WorkloadType = workloadType; this.Name = name; this.WorkloadInfo = CreateWorkloadInfo(workloadType, name, isService, out var activator); this.Activator = activator; }
static WorkloadInfo CreateWorkloadInfo(Type type, string name, IServiceProviderIsService isService, out Lazy <ObjectFactory> activator) { var ctors = type.GetConstructors(); if (ctors.Length == 0) { activator = new Lazy <ObjectFactory>(() => ActivatorUtilities.CreateFactory(type, Array.Empty <Type>())); return(new WorkloadInfo(name, Array.Empty <WorkloadParameterInfo>())); } if (ctors.Length != 1) { throw new InvalidOperationException("Workload constructor only allows zero or one. Type:" + type.FullName); } var ctor = ctors[0]; var parameters = ctor.GetParameters(); if (parameters.Length == 0) { activator = new Lazy <ObjectFactory>(() => ActivatorUtilities.CreateFactory(type, Array.Empty <Type>())); return(new WorkloadInfo(name, Array.Empty <WorkloadParameterInfo>())); } var parameterTypes = parameters.Where(x => !isService.IsService(x.ParameterType)); var arguments = parameterTypes .Select(p => { var name = p.Name; var enumNames = Array.Empty <string>(); var elementType = p.ParameterType; var parameterType = ConvertToAllowParameterType(ref elementType, out var isNullable, out var isArray); if (parameterType == null) { throw new InvalidOperationException($"Not allowed parameter type. Type:{ctor.DeclaringType!.FullName} Parameter:{type.FullName}"); } var enumTypeName = (parameterType == AllowParameterType.Enum) ? elementType.Name : null; if (parameterType == AllowParameterType.Enum) { enumNames = Enum.GetNames(elementType); } var defaultValue = p.HasDefaultValue ? p.DefaultValue : null; if (parameterType == AllowParameterType.Enum && p.HasDefaultValue) { defaultValue = Enum.GetName(elementType, defaultValue !); } return(new WorkloadParameterInfo(parameterType.Value, isNullable, isArray, defaultValue, name !, enumNames, enumTypeName)); }) .ToArray(); activator = new Lazy <ObjectFactory>(() => ActivatorUtilities.CreateFactory(type, parameterTypes.Select(x => x.ParameterType).ToArray())); return(new WorkloadInfo(name, arguments)); }
DFrameWorkloadCollection(Assembly[] searchAssemblies, bool includesDefault, IServiceProviderIsService isService) { dframeTypes = new Dictionary <string, DFrameWorkloadTypeInfo>(StringComparer.InvariantCultureIgnoreCase); foreach (var asm in searchAssemblies) { if (asm.FullName !.StartsWith("System") || asm.FullName.StartsWith("Microsoft.Extensions")) { continue; } Type[] types; try { types = asm.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types.Where(x => x != null).ToArray() !; } foreach (var workload in types) { if (typeof(Workload).IsAssignableFrom(workload) && !workload.IsAbstract) { #if !UNITY_2020_1_OR_NEWER var isDefault = workload.GetCustomAttribute <DefaultWorkloadAttribute>(true); if (isDefault != null) { if (!includesDefault) { continue; } } #endif var attr = workload.GetCustomAttribute <WorkloadAttribute>(false); var name = attr?.Name ?? workload.Name; var t = new DFrameWorkloadTypeInfo(workload, name, isService); if (!dframeTypes.TryAdd(name, t)) { throw new InvalidOperationException($"Worker name is duplicate. name:{name}, type:{t.WorkloadType.FullName}"); } } } } }
DFrameWorkerApp(DFrameWorkerOptions options, IServiceProviderIsService isService, IServiceProvider serviceProvider) { var workloadCollection = DFrameWorkloadCollection.FromAssemblies(options.WorkloadAssemblies, options.IncludesDefaultHttpWorkload, isService); #if UNITY_2020_1_OR_NEWER var logger = new ILogger <DFrameWorkerEngine>(); #else var logger = serviceProvider.GetRequiredService <ILogger <DFrameWorkerEngine> >(); #endif foreach (var item in workloadCollection.All) { logger.LogInformation($"Loaded {item.Name} workload."); } this.engines = new DFrameWorkerEngine[Math.Max(1, options.VirtualProcess)]; for (int i = 0; i < engines.Length; i++) { engines[i] = new DFrameWorkerEngine(logger, workloadCollection, options, isService, serviceProvider); } }
public static DFrameWorkloadCollection FromAssemblies(Assembly[] searchAssemblies, bool includesDefault, IServiceProviderIsService isService) { return(new DFrameWorkloadCollection(searchAssemblies, includesDefault, isService)); }