private static string WriteExtenders(PropertyInfo p, out bool isValidatable)
        {
            isValidatable = false;
            StringBuilder sb = new StringBuilder();

            sb.Append(".extend({ editState : false, disableValidation : false, empty : true })");

            RequiredAttribute requiredAttribute = p.GetCustomAttribute <RequiredAttribute>();

            if (requiredAttribute != null)
            {
                sb.Append($".extend({{ required: {{ message: \"{requiredAttribute.FormatErrorMessage(p.Name)}\", onlyIf: function() {{ return ko.utils.isPropertyValidatable(self, \"{ p.Name}\"); }} }} }})");
                isValidatable = true;
            }

            MinLengthAttribute minLengthAttribute = p.GetCustomAttribute <MinLengthAttribute>();

            if (minLengthAttribute != null)
            {
                sb.Append(string.Format(".extend({ minLength: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", minLengthAttribute.FormatErrorMessage(p.Name), minLengthAttribute.Length, p.Name));
                isValidatable = true;
            }

            MaxLengthAttribute maxLengthAttribute = p.GetCustomAttribute <MaxLengthAttribute>();

            if (maxLengthAttribute != null)
            {
                sb.Append(string.Format(".extend({ maxLength: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", maxLengthAttribute.FormatErrorMessage(p.Name), maxLengthAttribute.Length, p.Name));
                isValidatable = true;
            }

            RegularExpressionAttribute regularExpressionAttribute = p.GetCustomAttribute <RegularExpressionAttribute>();

            if (regularExpressionAttribute != null)
            {
                sb.Append(string.Format(".extend({ pattern: { message: \"{0}\", params: /{1}/, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", regularExpressionAttribute.FormatErrorMessage(p.Name), regularExpressionAttribute.Pattern, p.Name));
                isValidatable = true;
            }

            UrlAttribute urlAttribute = p.GetCustomAttribute <UrlAttribute>();

            if (urlAttribute != null)
            {
                sb.Append(string.Format(".extend({ pattern: { message: \"{0}\", params: /{1}/, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", urlAttribute.FormatErrorMessage(p.Name), urlAttribute, p.Name));
                isValidatable = true;
            }

            DateAttribute dateAttribute = p.GetCustomAttribute <DateAttribute>();

            if (dateAttribute != null)
            {
                sb.Append(string.Format(".extend({ date: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } })", dateAttribute.FormatErrorMessage(p.Name), p.Name));
                isValidatable = true;
            }

            NumericAttribute numericAttribute = p.GetCustomAttribute <NumericAttribute>();

            if (numericAttribute != null)
            {
                sb.Append(
                    string.Format(".extend({ number: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } }).extend({ numeric: {2} })",
                                  numericAttribute.FormatErrorMessage(p.Name), p.Name, numericAttribute.Precision));
                isValidatable = true;
            }

            EmailAttribute emailAttribute = p.GetCustomAttribute <EmailAttribute>();

            if (emailAttribute != null)
            {
                sb.Append(string.Format(".extend({ email: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } })", emailAttribute.FormatErrorMessage(p.Name), p.Name));
                isValidatable = true;
            }

            DigitsAttribute digitsAttribute = p.GetCustomAttribute <DigitsAttribute>();

            if (digitsAttribute != null)
            {
                sb.Append(string.Format(".extend({ digit: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } }).extend({ numeric: 0 })", digitsAttribute.FormatErrorMessage(p.Name), p.Name));
                isValidatable = true;
            }

            MinAttribute minAttribute = p.GetCustomAttribute <MinAttribute>();

            if (minAttribute != null)
            {
                sb.Append(string.Format(".extend({ min: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", minAttribute.FormatErrorMessage(p.Name), minAttribute.Min, p.Name));
                isValidatable = true;
            }

            MaxAttribute maxAttribute = p.GetCustomAttribute <MaxAttribute>();

            if (maxAttribute != null)
            {
                sb.Append(string.Format(".extend({ max: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", maxAttribute.FormatErrorMessage(p.Name), maxAttribute.Max, p.Name));
                isValidatable = true;
            }

            EqualToAttribute equalToAttribute = p.GetCustomAttribute <EqualToAttribute>();

            if (equalToAttribute != null)
            {
                sb.Append(string.Format(".extend({ equal: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", equalToAttribute.FormatErrorMessage(p.Name), equalToAttribute.OtherProperty, p.Name));
                isValidatable = true;
            }

            CompareAttribute compareAttribute = p.GetCustomAttribute <CompareAttribute>();

            if (compareAttribute != null)
            {
                sb.Append(string.Format(".extend({ equal: { message: \"{0}\", params: \"{1}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", compareAttribute.FormatErrorMessage(p.Name), compareAttribute.OtherProperty, p.Name));
                isValidatable = true;
            }

            FormatterAttribute formatterAttribute = p.GetCustomAttribute <FormatterAttribute>();

            if (formatterAttribute != null)
            {
                sb.Append(string.Format(".formatted({0}, {1})", formatterAttribute.Formatter, JsonConvert.SerializeObject(formatterAttribute.Arguments)));
            }

            return(sb.ToString());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 加载 DLL 插件。
        /// </summary>
        /// <param name="dllFiles">DLL 插件列表。</param>
        private void LoadDllPlugins(string[] dllFiles)
        {
            foreach (string file in dllFiles)
            {
                try
                {
                    _logger.LogDebug($"Loading plugin: {file}");

                    Assembly pluginAssembly = LoadPlugin(file);
                    Type[]   exportedTypes  = pluginAssembly.GetExportedTypes();

                    string pluginName = pluginAssembly.FullName;

                    _logger.LogDebug($"Parsing meta in plugin: {pluginName}");

                    Type[] metaTypes = exportedTypes.Where(type =>
                                                           Attribute.GetCustomAttribute(type, typeof(RmboxPluginAttribute)) is not null).ToArray();

                    if (metaTypes.Length != 1)
                    {
                        string err = $"插件 {pluginName} 具有的元信息的个数 {metaTypes.Length} 不符合 1 的要求。";
                        _logger.LogError(err);
                        throw new IndexOutOfRangeException(err);
                    }

                    // ReSharper disable once UseNegatedPatternMatching
                    IMeta pluginMeta = Activator.CreateInstance(metaTypes.Single()) as IMeta;
                    if (pluginMeta is null)
                    {
                        string err = $"在加载插件 {pluginName} 的元信息时发生错误。";
                        _logger.LogError(err);
                        throw new ArgumentNullException(nameof(pluginMeta));
                    }

                    _logger.LogDebug($"Meta parsed in: {pluginMeta.Name}");

                    MetaCollection.Add((pluginMeta, pluginAssembly));

                    _logger.LogDebug($"Parsing components in plugin: {pluginMeta.Name}");

                    List <Type> operationTypes = exportedTypes.Where(type =>
                                                                     Attribute.GetCustomAttribute(type, typeof(OperationAttribute)) is not null).ToList();

                    foreach (Type t in operationTypes.Where(type => !type.IsAssignableTo(typeof(IOperation)))
                             .ToArray())
                    {
                        _logger.LogWarning($"检测到错误导出的类型 {t.FullName},将会忽略加载。");
                        operationTypes.Remove(t);
                    }

                    foreach (Type operationType in operationTypes)
                    {
                        OperationAttribute operationAttribute =
                            Attribute.GetCustomAttribute(operationType, typeof(OperationAttribute))
                            as OperationAttribute;

                        OperationCollection.Add((operationAttribute, pluginMeta, operationType));

                        _logger.LogDebug($"Operation {operationAttribute.Name} loaded.");
                    }

                    List <Type> configSectionTypes = exportedTypes.Where(type =>
                                                                         Attribute.GetCustomAttribute(type, typeof(ConfigSectionAttribute)) is not null).ToList();

                    foreach (Type t in configSectionTypes.Where(type => !type.IsSubclassOf(typeof(ConfigSectionBase)))
                             .ToArray())
                    {
                        _logger.LogWarning($"检测到错误导出的类型 {t.FullName},将会忽略加载。");
                        configSectionTypes.Remove(t);
                    }

                    foreach (Type configSectionType in configSectionTypes)
                    {
                        var configSectionAttribute =
                            Attribute.GetCustomAttribute(configSectionType, typeof(ConfigSectionAttribute))
                            as ConfigSectionAttribute;

                        ConfigSectionCollection.Add((configSectionAttribute, configSectionType));

                        _logger.LogDebug($"Config section {configSectionAttribute.Id} loaded.");
                    }

                    List <Type> formatterTypes = exportedTypes.Where(type =>
                                                                     Attribute.GetCustomAttribute(type, typeof(FormatterAttribute)) is not null).ToList();

                    foreach (Type t in formatterTypes.Where(type => !type.IsAssignableTo(typeof(IFormatter)))
                             .ToArray())
                    {
                        _logger.LogWarning($"检测到错误导出的类型 {t.FullName},将会忽略加载。");
                        formatterTypes.Remove(t);
                    }

                    foreach (Type formatterType in formatterTypes)
                    {
                        FormatterAttribute formatterAttribute =
                            Attribute.GetCustomAttribute(formatterType, typeof(FormatterAttribute))
                            as FormatterAttribute;

                        FormatterCollection.Add((formatterAttribute, formatterType));

                        _logger.LogDebug($"Formatter {formatterType.FullName} loaded.");
                    }

                    _logger.LogDebug($"Plugin {pluginMeta.Name} loaded.");
                }
                catch (Exception e)
                {
                    _logger.LogWarning(e, $"在加载插件 {file} 时发生错误。将跳过该插件的加载。");
                }
            }
        }