private ComponentEntrypoint(bool is_singleton, Type instance_type, ExpressionFactory.Call method, ExpressionFactory.GetProperty <object> task_result_prop, Type[] imports, Type[] exports, TwConstraint[] constraints, FieldInfo[] tuple_fields, TwEntrypointPriorityEnum priority, bool is_async)
        {
            _isSingleton       = is_singleton;
            _method            = method;
            _taskResultPoperty = task_result_prop;
            _tupleFields       = tuple_fields;
            InstanceType       = instance_type;

            Priority = priority;
            IsAsync  = is_async;

            var(export, exportIsOptions) = ExpressionFactory.GetExpandedTypes(exports);
            _export         = export;
            _exportIsOption = exportIsOptions;

            var(import, importIsOptions) = ExpressionFactory.GetExpandedTypes(imports);
            _import         = import;
            _importIsOption = importIsOptions;

            _constraints = constraints;
        }
        public static ComponentEntrypoint Create(MethodInfo method, TwEntrypointPriorityEnum priority)
        {
            var type    = method.DeclaringType;
            var param   = method.GetParameters();
            var export  = method.ReturnType == typeof(void) ? null : method.ReturnType;
            var isAsync = export != null && (export == typeof(Task) || export.IsSubclassOf(typeof(Task)));

            export = isAsync ? export.IsGenericType ? export.GenericTypeArguments.Single() : null : export;

            var imports       = param.Select(p => p.ParameterType).ToArray();
            var isMultipleRet = export?.IsGenericType ?? false?_valueTupleTypes.Contains(export.GetGenericTypeDefinition()) : false;

            var exports = isMultipleRet ? export.GenericTypeArguments : export != null ? new[] { export } : Array.Empty <Type>();

            var getTaskResultProperty = isAsync && export != null?ExpressionFactory.GetPropertyExecutor <object>(typeof(Task <>).MakeGenericType(method.ReturnType.GenericTypeArguments.Single()).GetProperty("Result")) : null;

            var tupleFields = isMultipleRet ? export.GetFields() : null;
            var callMethod  = ExpressionFactory.GetMethodExecutor(method);

            var constraints = GetConstraints(method, type);

            return(new ComponentEntrypoint(method.IsStatic, type, callMethod, getTaskResultProperty, imports, exports, constraints, tupleFields, priority, isAsync));
        }
 public TwEntrypointAttribute(TwEntrypointPriorityEnum priority = TwEntrypointPriorityEnum.Medium)
 {
     Priority = priority;
 }