Browse Source

#44 Clock abstraction and json serializer abstraction.

pull/81/head
Halil İbrahim Kalkan 9 years ago
parent
commit
ffc1977c16
  1. 9
      src/Volo.Abp/Volo/Abp/Json/IJsonSerializer.cs
  2. 34
      src/Volo.Abp/Volo/Abp/Json/JsonExtensions.cs
  3. 46
      src/Volo.Abp/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs
  4. 45
      src/Volo.Abp/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs
  5. 42
      src/Volo.Abp/Volo/Abp/Timing/Clock.cs
  6. 17
      src/Volo.Abp/Volo/Abp/Timing/ClockOptions.cs
  7. 29
      src/Volo.Abp/Volo/Abp/Timing/IClock.cs
  8. 6
      test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs

9
src/Volo.Abp/Volo/Abp/Json/IJsonSerializer.cs

@ -0,0 +1,9 @@
namespace Volo.Abp.Json
{
public interface IJsonSerializer
{
string Serialize(object obj, bool camelCase = false, bool indented = false);
T Deserialize<T>(string jsonString);
}
}

34
src/Volo.Abp/Volo/Abp/Json/JsonExtensions.cs

@ -1,34 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Volo.Abp.Json
{
public static class JsonExtensions
{
//TODO: Remove this extension method, create IJsonSerializer abstraction (if there is not already such an abstraction).
/// <summary>
/// Converts given object to JSON string.
/// </summary>
/// <returns></returns>
public static string ToJsonString(this object obj, bool camelCase = false, bool indented = false)
{
var options = new JsonSerializerSettings();
if (camelCase)
{
options.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
if (indented)
{
options.Formatting = Formatting.Indented;
}
//TODO: AbpDateTimeConverter contains Clock, so it should be injected!
//options.Converters.Insert(0, new AbpDateTimeConverter());
return JsonConvert.SerializeObject(obj, options);
}
}
}

46
src/Volo.Abp/Volo/Abp/Json/Newtonsoft/AbpJsonIsoDateTimeConverter.cs

@ -0,0 +1,46 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Volo.Abp.Timing;
using Volo.DependencyInjection;
namespace Volo.Abp.Json.Newtonsoft
{
public class AbpJsonIsoDateTimeConverter : IsoDateTimeConverter, ITransientDependency
{
private readonly IClock _clock;
public AbpJsonIsoDateTimeConverter(IClock clock)
{
_clock = clock;
}
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
{
return true;
}
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var date = base.ReadJson(reader, objectType, existingValue, serializer) as DateTime?;
if (date.HasValue)
{
return _clock.Normalize(date.Value);
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var date = value as DateTime?;
base.WriteJson(writer, date.HasValue ? _clock.Normalize(date.Value) : value, serializer);
}
}
}

45
src/Volo.Abp/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs

@ -0,0 +1,45 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Volo.DependencyInjection;
namespace Volo.Abp.Json.Newtonsoft
{
public class NewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency
{
private readonly AbpJsonIsoDateTimeConverter _dateTimeConverter;
public NewtonsoftJsonSerializer(AbpJsonIsoDateTimeConverter dateTimeConverter)
{
_dateTimeConverter = dateTimeConverter;
}
public string Serialize(object obj, bool camelCase = false, bool indented = false)
{
var serializerSettings = CreateDefaultSerializerSettings();
if (camelCase)
{
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
if (indented)
{
serializerSettings.Formatting = Formatting.Indented;
}
return JsonConvert.SerializeObject(obj, serializerSettings);
}
protected virtual JsonSerializerSettings CreateDefaultSerializerSettings()
{
var settings = new JsonSerializerSettings();
settings.Converters.Insert(0, _dateTimeConverter);
return settings;
}
public T Deserialize<T>(string jsonString)
{
return JsonConvert.DeserializeObject<T>(jsonString);
}
}
}

42
src/Volo.Abp/Volo/Abp/Timing/Clock.cs

@ -0,0 +1,42 @@
using System;
using Microsoft.Extensions.Options;
using Volo.DependencyInjection;
namespace Volo.Abp.Timing
{
public class Clock : IClock, ITransientDependency
{
protected ClockOptions Options { get; }
public Clock(IOptions<ClockOptions> options)
{
Options = options.Value;
}
public virtual DateTime Now => Options.Kind == DateTimeKind.Utc ? DateTime.UtcNow : DateTime.Now;
public virtual DateTimeKind Kind => Options.Kind;
public virtual bool SupportsMultipleTimezone => Options.Kind == DateTimeKind.Utc;
public virtual DateTime Normalize(DateTime dateTime)
{
if (Kind == DateTimeKind.Unspecified || Kind == dateTime.Kind)
{
return dateTime;
}
if (Kind == DateTimeKind.Local && dateTime.Kind == DateTimeKind.Utc)
{
return dateTime.ToLocalTime();
}
if (Kind == DateTimeKind.Utc && dateTime.Kind == DateTimeKind.Local)
{
return dateTime.ToUniversalTime();
}
return DateTime.SpecifyKind(dateTime, Kind);
}
}
}

17
src/Volo.Abp/Volo/Abp/Timing/ClockOptions.cs

@ -0,0 +1,17 @@
using System;
namespace Volo.Abp.Timing
{
public class ClockOptions
{
/// <summary>
/// Default: <see cref="DateTimeKind.Unspecified"/>
/// </summary>
public DateTimeKind Kind { get; set; }
public ClockOptions()
{
Kind = DateTimeKind.Unspecified;
}
}
}

29
src/Volo.Abp/Volo/Abp/Timing/IClock.cs

@ -0,0 +1,29 @@
using System;
namespace Volo.Abp.Timing
{
public interface IClock
{
/// <summary>
/// Gets Now.
/// </summary>
DateTime Now { get; }
/// <summary>
/// Gets kind.
/// </summary>
DateTimeKind Kind { get; }
/// <summary>
/// Is that provider supports multiple time zone.
/// </summary>
bool SupportsMultipleTimezone { get; }
/// <summary>
/// Normalizes given <see cref="DateTime"/>.
/// </summary>
/// <param name="dateTime">DateTime to be normalized.</param>
/// <returns>Normalized DateTime</returns>
DateTime Normalize(DateTime dateTime);
}
}

6
test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs

@ -24,13 +24,15 @@ namespace Volo.Abp.AspNetCore.App
app.Run(async (ctx) =>
{
var manager = ctx.RequestServices.GetRequiredService<IMultiTenancyManager>();
var jsonSerializer = ctx.RequestServices.GetRequiredService<IJsonSerializer>();
var dictionary = new Dictionary<string, string>
{
["TenantId"] = manager.CurrentTenant?.Id ?? ""
};
await ctx.Response.WriteAsync(dictionary.ToJsonString());
var result = jsonSerializer.Serialize(dictionary);
await ctx.Response.WriteAsync(result);
});
}
}

Loading…
Cancel
Save