Skip to content

Commit

Permalink
Merge pull request #10732 from abpframework/maliming/IValueValidatorF…
Browse files Browse the repository at this point in the history
…actory

Add `IValueValidatorFactory`
  • Loading branch information
hikalkan authored Jan 10, 2022
2 parents b5b9fb3 + 3b12c26 commit bc00752
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.FeatureManagement.JsonConverters;
Expand All @@ -25,14 +26,20 @@ public override void ConfigureServices(ServiceConfigurationContext context)
options.FileSets.AddEmbedded<AbpFeatureManagementApplicationContractsModule>();
});

var contractsOptionsActions = context.Services.GetPreConfigureActions<AbpFeatureManagementApplicationContractsOptions>();
Configure<AbpFeatureManagementApplicationContractsOptions>(options =>
{
contractsOptionsActions.Configure(options);
});

Configure<AbpNewtonsoftJsonSerializerOptions>(options =>
{
options.Converters.Add<NewtonsoftStringValueTypeJsonConverter>();
});

Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter());
options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter(contractsOptionsActions.Configure()));
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Generic;
using Volo.Abp.FeatureManagement.JsonConverters;
using Volo.Abp.Validation.StringValues;

namespace Volo.Abp.FeatureManagement;

public class AbpFeatureManagementApplicationContractsOptions
{
public HashSet<IValueValidatorFactory> ValueValidatorFactory { get; }

public AbpFeatureManagementApplicationContractsOptions()
{
ValueValidatorFactory = new HashSet<IValueValidatorFactory>
{
new ValueValidatorFactory<AlwaysValidValueValidator>("NULL"),
new ValueValidatorFactory<BooleanValueValidator>("BOOLEAN"),
new ValueValidatorFactory<NumericValueValidator>("NUMERIC"),
new ValueValidatorFactory<StringValueValidator>("STRING")
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Volo.Abp.Validation.StringValues;

namespace Volo.Abp.FeatureManagement.JsonConverters;

public interface IValueValidatorFactory
{
bool CanCreate(string name);

IValueValidator Create();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Volo.Abp.DependencyInjection;
Expand All @@ -13,6 +14,13 @@ public class NewtonsoftStringValueTypeJsonConverter : JsonConverter, ITransientD
{
public override bool CanWrite => false;

protected readonly AbpFeatureManagementApplicationContractsOptions Options;

public NewtonsoftStringValueTypeJsonConverter(IOptions<AbpFeatureManagementApplicationContractsOptions> options)
{
Options = options.Value;
}

public override bool CanConvert(Type objectType)
{
return objectType == typeof(IStringValueType);
Expand Down Expand Up @@ -77,13 +85,11 @@ protected virtual IStringValueType CreateStringValueTypeByName(JObject jObject,

protected virtual IValueValidator CreateValueValidatorByName(JToken jObject, string name)
{
return name switch
foreach (var factory in Options.ValueValidatorFactory.Where(factory => factory.CanCreate(name)))
{
"NULL" => new AlwaysValidValueValidator(),
"BOOLEAN" => new BooleanValueValidator(),
"NUMERIC" => new NumericValueValidator(),
"STRING" => new StringValueValidator(),
_ => throw new ArgumentException($"{nameof(IValueValidator)} named {name} was not found!")
};
return factory.Create();
}

throw new ArgumentException($"{nameof(IValueValidator)} named {name} was cannot be created!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ public class StringValueTypeJsonConverter : JsonConverter<IStringValueType>

private JsonSerializerOptions _writeJsonSerializerOptions;

protected readonly AbpFeatureManagementApplicationContractsOptions Options;

public StringValueTypeJsonConverter(AbpFeatureManagementApplicationContractsOptions options)
{
Options = options;
}

public override IStringValueType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
Expand All @@ -21,7 +28,8 @@ public override IStringValueType Read(ref Utf8JsonReader reader, Type typeToConv
{
var name = nameJsonProperty.Value.GetString();

_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this, new ValueValidatorJsonConverter(), new SelectionStringValueItemSourceJsonConverter());
_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this, new ValueValidatorJsonConverter(Options),
new SelectionStringValueItemSourceJsonConverter());

return name switch
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Volo.Abp.Validation.StringValues;

namespace Volo.Abp.FeatureManagement.JsonConverters;

public class ValueValidatorFactory<TValueValidator> : IValueValidatorFactory
where TValueValidator : IValueValidator, new()
{
protected readonly string Name;

public ValueValidatorFactory(string name)
{
Name = name;
}

public bool CanCreate(string name)
{
return Name == name;
}

public IValueValidator Create()
{
return new TValueValidator() as IValueValidator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ public class ValueValidatorJsonConverter : JsonConverter<IValueValidator>

private JsonSerializerOptions _writeJsonSerializerOptions;

protected readonly AbpFeatureManagementApplicationContractsOptions Options;

public ValueValidatorJsonConverter(AbpFeatureManagementApplicationContractsOptions options)
{
Options = options;
}

public override IValueValidator Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
Expand Down Expand Up @@ -51,13 +58,11 @@ public override void Write(Utf8JsonWriter writer, IValueValidator value, JsonSer

protected virtual IValueValidator CreateValueValidatorByName(string name)
{
return name switch
foreach (var factory in Options.ValueValidatorFactory.Where(factory => factory.CanCreate(name)))
{
"NULL" => new AlwaysValidValueValidator(),
"BOOLEAN" => new BooleanValueValidator(),
"NUMERIC" => new NumericValueValidator(),
"STRING" => new StringValueValidator(),
_ => throw new ArgumentException($"{nameof(IValueValidator)} named {name} was not found!")
};
return factory.Create();
}

throw new ArgumentException($"{nameof(IValueValidator)} named {name} was cannot be created!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ public override void ConfigureServices(ServiceConfigurationContext context)
.AddBaseTypes(typeof(AbpUiResource));
});

var contractsOptions = context.Services.ExecutePreConfiguredActions<AbpFeatureManagementApplicationContractsOptions>();
Configure<JsonOptions>(options =>
{
options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter());
options.JsonSerializerOptions.Converters.AddIfNotContains(new StringValueTypeJsonConverter(contractsOptions));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ protected override void AfterAddApplication(IServiceCollection services)
{
services.PreConfigure<AbpJsonOptions>(options =>
{
options.UseHybridSerializer = true;
options.UseHybridSerializer = false;
});
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.FeatureManagement.JsonConverters;
using Volo.Abp.Json;
using Volo.Abp.Validation.StringValues;
using Xunit;
Expand All @@ -16,6 +18,16 @@ public StringValueJsonConverter_Tests()
_jsonSerializer = GetRequiredService<IJsonSerializer>();
}

protected override void BeforeAddApplication(IServiceCollection services)
{
services.PreConfigure<AbpFeatureManagementApplicationContractsOptions>(options =>
{
options.ValueValidatorFactory.Add(new ValueValidatorFactory<UrlValueValidator>("URL"));
});

base.BeforeAddApplication(services);
}

[Fact]
public void Should_Serialize_And_Deserialize()
{
Expand Down Expand Up @@ -67,6 +79,13 @@ public void Should_Serialize_And_Deserialize()
Name = "FeatureName",
Key = "FeatureKey"
}
},
new FeatureDto
{
ValueType = new FreeTextStringValueType
{
Validator = new UrlValueValidator("https")
}
}
}
}
Expand Down Expand Up @@ -95,5 +114,9 @@ public void Should_Serialize_And_Deserialize()

featureListDto2.Groups[0].Features[3].Provider.Name.ShouldBe("FeatureName");
featureListDto2.Groups[0].Features[3].Provider.Key.ShouldBe("FeatureKey");

featureListDto2.Groups[0].Features[4].ValueType.ShouldBeOfType<FreeTextStringValueType>();
featureListDto2.Groups[0].Features[4].ValueType.Validator.ShouldBeOfType<UrlValueValidator>();
featureListDto2.Groups[0].Features[4].ValueType.Validator.As<UrlValueValidator>().Scheme.ShouldBe("https");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ protected override void AfterAddApplication(IServiceCollection services)
{
services.PreConfigure<AbpJsonOptions>(options =>
{
options.UseHybridSerializer = false;
options.UseHybridSerializer = true;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using Volo.Abp.Validation.StringValues;

namespace Volo.Abp.FeatureManagement;

[Serializable]
[ValueValidator("URL")]
public class UrlValueValidator : ValueValidatorBase
{
public string Scheme {
get => this["Scheme"].ToString();
set => this["Scheme"] = value;
}

public UrlValueValidator()
{

}

public UrlValueValidator(string scheme)
{
Scheme = scheme;
}

public override bool IsValid(object value)
{
var s = value.ToString();
return s != null && s.StartsWith(Scheme);
}
}

0 comments on commit bc00752

Please sign in to comment.