예제 #1
0
 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;
 }
예제 #2
0
        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));
        }
예제 #3
0
        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}");
                        }
                    }
                }
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
 public static DFrameWorkloadCollection FromAssemblies(Assembly[] searchAssemblies, bool includesDefault, IServiceProviderIsService isService)
 {
     return(new DFrameWorkloadCollection(searchAssemblies, includesDefault, isService));
 }