Browse Source

Add `AbpIncludeNonPublicPropertiesModifiers` when `AddEntityCache`.

pull/15191/head
maliming 4 years ago
parent
commit
796cd1b0e5
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 29
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs
  2. 8
      framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs
  3. 22
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIncludeNonPublicPropertiesModifiers_Tests.cs
  4. 14
      framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs
  5. 28
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityCache_Tests.cs

29
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs

@ -4,6 +4,8 @@ using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Json.SystemTextJson.Modifiers;
namespace Volo.Abp.Domain.Entities.Caching; namespace Volo.Abp.Domain.Entities.Caching;
@ -11,7 +13,7 @@ public static class EntityCacheServiceCollectionExtensions
{ {
public static IServiceCollection AddEntityCache<TEntity, TKey>( public static IServiceCollection AddEntityCache<TEntity, TKey>(
this IServiceCollection services, this IServiceCollection services,
[CanBeNull] DistributedCacheEntryOptions cacheOptions = null) [CanBeNull] DistributedCacheEntryOptions cacheOptions = null)
where TEntity : Entity<TKey> where TEntity : Entity<TKey>
{ {
services services
@ -21,18 +23,23 @@ public static class EntityCacheServiceCollectionExtensions
>(); >();
services services
.TryAddTransient<EntityCacheWithoutCacheItem<TEntity, TKey>>(); .TryAddTransient<EntityCacheWithoutCacheItem<TEntity, TKey>>();
services.Configure<AbpDistributedCacheOptions>(options => services.Configure<AbpDistributedCacheOptions>(options =>
{ {
options.ConfigureCache<TEntity>(cacheOptions ?? GetDefaultCacheOptions()); options.ConfigureCache<TEntity>(cacheOptions ?? GetDefaultCacheOptions());
}); });
services.Configure<AbpSystemTextJsonSerializerModifiersOptions>(options =>
{
options.Modifiers.Add(new AbpIncludeNonPublicPropertiesModifiers<TEntity, TKey>().CreateModifyAction(x => x.Id));
});
return services; return services;
} }
public static IServiceCollection AddEntityCache<TEntity, TEntityCacheItem, TKey>( public static IServiceCollection AddEntityCache<TEntity, TEntityCacheItem, TKey>(
this IServiceCollection services, this IServiceCollection services,
[CanBeNull] DistributedCacheEntryOptions cacheOptions = null) [CanBeNull] DistributedCacheEntryOptions cacheOptions = null)
where TEntity : Entity<TKey> where TEntity : Entity<TKey>
where TEntityCacheItem : class where TEntityCacheItem : class
{ {
@ -43,18 +50,18 @@ public static class EntityCacheServiceCollectionExtensions
>(); >();
services services
.TryAddTransient<EntityCacheWithObjectMapper<TEntity, TEntityCacheItem, TKey>>(); .TryAddTransient<EntityCacheWithObjectMapper<TEntity, TEntityCacheItem, TKey>>();
services.Configure<AbpDistributedCacheOptions>(options => services.Configure<AbpDistributedCacheOptions>(options =>
{ {
options.ConfigureCache<TEntityCacheItem>(cacheOptions ?? GetDefaultCacheOptions()); options.ConfigureCache<TEntityCacheItem>(cacheOptions ?? GetDefaultCacheOptions());
}); });
return services; return services;
} }
public static IServiceCollection AddEntityCache<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>( public static IServiceCollection AddEntityCache<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>(
this IServiceCollection services, this IServiceCollection services,
[CanBeNull] DistributedCacheEntryOptions cacheOptions = null) [CanBeNull] DistributedCacheEntryOptions cacheOptions = null)
where TEntity : Entity<TKey> where TEntity : Entity<TKey>
where TEntityCacheItem : class where TEntityCacheItem : class
{ {
@ -64,12 +71,12 @@ public static class EntityCacheServiceCollectionExtensions
EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey> EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>
>(); >();
services.TryAddTransient<EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>>(); services.TryAddTransient<EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>>();
services.Configure<AbpDistributedCacheOptions>(options => services.Configure<AbpDistributedCacheOptions>(options =>
{ {
options.ConfigureCache<TEntityCacheItem>(cacheOptions ?? GetDefaultCacheOptions()); options.ConfigureCache<TEntityCacheItem>(cacheOptions ?? GetDefaultCacheOptions());
}); });
return services; return services;
} }
@ -79,4 +86,4 @@ public static class EntityCacheServiceCollectionExtensions
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2) AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2)
}; };
} }
} }

8
framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/Modifiers/AbpIncludeNonPublicPropertiesModifiers.cs

@ -28,14 +28,10 @@ public class AbpIncludeNonPublicPropertiesModifiers<TClass, TProperty>
x.Set == null); x.Set == null);
if (propertyJsonInfo != null) if (propertyJsonInfo != null)
{ {
var propertyInfo = typeof(TClass).GetProperty(propertyName, BindingFlags.NonPublic); var propertyInfo = typeof(TClass).GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (propertyInfo != null) if (propertyInfo != null)
{ {
var jsonPropertyInfo = jsonTypeInfo.CreateJsonPropertyInfo(typeof(TProperty), propertyJsonInfo.Name); propertyJsonInfo.Set = propertyInfo.SetValue;
jsonPropertyInfo.Get = propertyInfo.GetValue;
jsonPropertyInfo.Set = propertyInfo.SetValue;
jsonTypeInfo.Properties.Remove(propertyJsonInfo);
jsonTypeInfo.Properties.Add(jsonPropertyInfo);
} }
} }
} }

22
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpIncludeNonPublicPropertiesModifiers_Tests.cs

@ -29,10 +29,14 @@ public class AbpIncludeNonPublicPropertiesModifiers_Tests : AbpJsonTestBase
[Fact] [Fact]
public void Test() public void Test()
{ {
var json = _jsonSerializer.Serialize(new NonPublicPropertiesClass() var model = new NonPublicPropertiesClass
{ {
Id = "id" Id = "id"
}); };
model.SetName("my-name");
model.SetAge("42");
var json = _jsonSerializer.Serialize(model);
json.ShouldContain("id"); json.ShouldContain("id");
json.ShouldContain("name"); json.ShouldContain("name");
@ -40,8 +44,8 @@ public class AbpIncludeNonPublicPropertiesModifiers_Tests : AbpJsonTestBase
var obj = _jsonSerializer.Deserialize<NonPublicPropertiesClass>(json); var obj = _jsonSerializer.Deserialize<NonPublicPropertiesClass>(json);
obj.Id.ShouldBe("id"); obj.Id.ShouldBe("id");
obj.Name.ShouldBe("name"); obj.Name.ShouldBe("my-name");
obj.Age.ShouldBe("age"); obj.Age.ShouldBe("42");
} }
class NonPublicPropertiesClass class NonPublicPropertiesClass
@ -52,10 +56,14 @@ public class AbpIncludeNonPublicPropertiesModifiers_Tests : AbpJsonTestBase
public string Age { get; protected set; } public string Age { get; protected set; }
public NonPublicPropertiesClass() public void SetName(string name)
{
Name = name;
}
public void SetAge(string age)
{ {
Name = "name"; Age = age;
Age = "age";
} }
} }
} }

14
framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs

@ -1,11 +1,12 @@
using System; using System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.TestApp.MemoryDb; using Volo.Abp.TestApp.MemoryDb;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.MemoryDb; using Volo.Abp.Domain.Repositories.MemoryDb;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.MemoryDb.JsonConverters; using Volo.Abp.MemoryDb.JsonConverters;
using Volo.Abp.TestApp; using Volo.Abp.TestApp;
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
@ -33,9 +34,12 @@ public class AbpMemoryDbTestModule : AbpModule
options.AddRepository<City, CityRepository>(); options.AddRepository<City, CityRepository>();
}); });
Configure<Utf8JsonMemoryDbSerializerOptions>(options => context.Services.AddOptions<Utf8JsonMemoryDbSerializerOptions>()
{ .Configure<IServiceProvider>((options, serviceProvider) =>
options.JsonSerializerOptions.Converters.Add(new EntityJsonConverter<EntityWithIntPk, int>()); {
}); options.JsonSerializerOptions.Converters.Add(new EntityJsonConverter<EntityWithIntPk, int>());
options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider
.GetRequiredService<IOptions<AbpSystemTextJsonSerializerModifiersOptions>>());
});
} }
} }

28
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityCache_Tests.cs

@ -25,7 +25,7 @@ public abstract class EntityCache_Tests<TStartupModule> : TestAppTestBase<TStart
ProductEntityCache = GetRequiredService<IEntityCache<Product, Guid>>(); ProductEntityCache = GetRequiredService<IEntityCache<Product, Guid>>();
ProductCacheItem = GetRequiredService<IEntityCache<ProductCacheItem, Guid>>(); ProductCacheItem = GetRequiredService<IEntityCache<ProductCacheItem, Guid>>();
} }
[Fact] [Fact]
public async Task Should_Return_Null_IF_Entity_Not_Exist() public async Task Should_Return_Null_IF_Entity_Not_Exist()
{ {
@ -41,28 +41,32 @@ public abstract class EntityCache_Tests<TStartupModule> : TestAppTestBase<TStart
await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductEntityCache.GetAsync(notExistId)); await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductEntityCache.GetAsync(notExistId));
await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductCacheItem.GetAsync(notExistId)); await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductCacheItem.GetAsync(notExistId));
} }
[Fact] [Fact]
public async Task Should_Return_EntityCache() public async Task Should_Return_EntityCache()
{ {
var product = await ProductEntityCache.FindAsync(TestDataBuilder.ProductId); var product = await ProductEntityCache.FindAsync(TestDataBuilder.ProductId);
product.ShouldNotBeNull(); product.ShouldNotBeNull();
product = await ProductEntityCache.FindAsync(TestDataBuilder.ProductId);
product.ShouldNotBeNull();
product.Id.ShouldBe(TestDataBuilder.ProductId); product.Id.ShouldBe(TestDataBuilder.ProductId);
product.Name.ShouldBe("Product1"); product.Name.ShouldBe("Product1");
product.Price.ShouldBe(decimal.One); product.Price.ShouldBe(decimal.One);
var productCacheItem = await ProductCacheItem.FindAsync(product.Id); var productCacheItem = await ProductCacheItem.FindAsync(product.Id);
productCacheItem.ShouldNotBeNull(); productCacheItem.ShouldNotBeNull();
productCacheItem = await ProductCacheItem.FindAsync(product.Id);
productCacheItem.ShouldNotBeNull();
productCacheItem.Id.ShouldBe(TestDataBuilder.ProductId); productCacheItem.Id.ShouldBe(TestDataBuilder.ProductId);
productCacheItem.Name.ShouldBe("Product1"); productCacheItem.Name.ShouldBe("Product1");
productCacheItem.Price.ShouldBe(decimal.One); productCacheItem.Price.ShouldBe(decimal.One);
} }
[Fact] [Fact]
public async Task Should_Return_Null_IF_Deleted() public async Task Should_Return_Null_IF_Deleted()
{ {
await ProductRepository.DeleteAsync(TestDataBuilder.ProductId); await ProductRepository.DeleteAsync(TestDataBuilder.ProductId);
(await ProductEntityCache.FindAsync(TestDataBuilder.ProductId)).ShouldBeNull(); (await ProductEntityCache.FindAsync(TestDataBuilder.ProductId)).ShouldBeNull();
(await ProductCacheItem.FindAsync(TestDataBuilder.ProductId)).ShouldBeNull(); (await ProductCacheItem.FindAsync(TestDataBuilder.ProductId)).ShouldBeNull();
} }
@ -77,13 +81,13 @@ public abstract class EntityCache_Tests<TStartupModule> : TestAppTestBase<TStart
product.Name = "Product2"; product.Name = "Product2";
product.Price = decimal.Zero; product.Price = decimal.Zero;
await ProductRepository.UpdateAsync(product); await ProductRepository.UpdateAsync(product);
product = await ProductEntityCache.FindAsync(product.Id); product = await ProductEntityCache.FindAsync(product.Id);
product.ShouldNotBeNull(); product.ShouldNotBeNull();
product.Id.ShouldBe(TestDataBuilder.ProductId); product.Id.ShouldBe(TestDataBuilder.ProductId);
product.Name.ShouldBe("Product2"); product.Name.ShouldBe("Product2");
product.Price.ShouldBe(decimal.Zero); product.Price.ShouldBe(decimal.Zero);
var productCacheItem = await ProductCacheItem.FindAsync(product.Id); var productCacheItem = await ProductCacheItem.FindAsync(product.Id);
productCacheItem.ShouldNotBeNull(); productCacheItem.ShouldNotBeNull();
productCacheItem.Id.ShouldBe(TestDataBuilder.ProductId); productCacheItem.Id.ShouldBe(TestDataBuilder.ProductId);
@ -95,6 +99,11 @@ public abstract class EntityCache_Tests<TStartupModule> : TestAppTestBase<TStart
[Serializable] [Serializable]
public class Product : FullAuditedAggregateRoot<Guid> public class Product : FullAuditedAggregateRoot<Guid>
{ {
public Product()
{
}
public Product(Guid id, string name, decimal price) public Product(Guid id, string name, decimal price)
: base(id) : base(id)
{ {
@ -102,9 +111,6 @@ public class Product : FullAuditedAggregateRoot<Guid>
Price = price; Price = price;
} }
[JsonInclude]
public override Guid Id { get; protected set; }
public string Name { get; set; } public string Name { get; set; }
public decimal Price { get; set; } public decimal Price { get; set; }
@ -119,4 +125,4 @@ public class ProductCacheItem
public string Name { get; set; } public string Name { get; set; }
public decimal Price { get; set; } public decimal Price { get; set; }
} }

Loading…
Cancel
Save