271 lines
11 KiB
C#
271 lines
11 KiB
C#
using gehGassiApp.Core.Interfaces;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using gehGassiApp.Domain.Dogs;
|
|
using gehGassiApp.Core.Data;
|
|
using gehGassiApp.Core.Interfaces.Synchronization;
|
|
|
|
namespace gehGassiApp.Core.Services
|
|
{
|
|
/// <summary>
|
|
/// Service der die Verwaltung von Hunderassen realisiert
|
|
/// </summary>
|
|
public class DogRaceService : ServiceBase<DogRace>, IDogRaceService
|
|
{
|
|
private readonly ICommunicationService _communicationService;
|
|
private readonly ISyncInfoPullService _syncInfoPullService;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="unitOfWork">Instanz eines IUnitOfWork</param>
|
|
/// <param name="communicationService">Instanz eines ICommunicationService</param>
|
|
/// <param name="syncInfoPullService">Instanz eines ISyncInfoPullService</param>
|
|
public DogRaceService(IUnitOfWork unitOfWork, ICommunicationService communicationService, ISyncInfoPullService syncInfoPullService) : base(unitOfWork)
|
|
{
|
|
_communicationService = communicationService;
|
|
_syncInfoPullService = syncInfoPullService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Entität anhand der eindeutigen Id zurück
|
|
/// </summary>
|
|
/// <param name="id">Id der Entität</param>
|
|
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
|
|
/// <returns>Entität oder null, wenn nicht gefunden</returns>
|
|
public override DogRace Get(object id, bool noTracking = true)
|
|
{
|
|
return Repository.SingleOrDefault(c => c.Id == id.ToString(), noTracking);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Entität anhand der eindeutigen Id zurück
|
|
/// </summary>
|
|
/// <param name="id">Id der Entität</param>
|
|
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
|
|
/// <returns>Entität oder null, wenn nicht gefunden</returns>
|
|
public override async Task<DogRace> GetAsync(object id, bool noTracking = true)
|
|
{
|
|
return await Repository.SingleOrDefaultAsync(c => c.Id == id.ToString(), noTracking).ConfigureAwait(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste der Hunderassen zurück.
|
|
/// Entweder von der DB oder vom Server
|
|
/// </summary>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Liste der Hunderassen</returns>
|
|
public async Task<List<DogRace>> GetRacesAsync(string language, string accessToken, CancellationToken token)
|
|
{
|
|
//Zuerst DB
|
|
var localRaces = await Repository.FindAsync(c => c.Deleted == false, noTracking: true).ConfigureAwait(false);
|
|
if (localRaces != null && localRaces.Any())
|
|
return localRaces.Where(c => c.Deleted == false).OrderBy(c => c.Name).ToList();
|
|
else
|
|
{
|
|
//Dann wenn lokal nicht verfügbar immer online...
|
|
var isConnected = await _communicationService.IsConnected();
|
|
//isConnected = false;
|
|
if (isConnected)
|
|
{
|
|
var racesResult = await _communicationService.GetDogRacesAsync(null, language, accessToken, token);
|
|
if (racesResult.Success)
|
|
{
|
|
var result = await HandleChangesAsync(racesResult.Value);
|
|
if (result.LastUpdate != null)
|
|
await _syncInfoPullService.AddOrUpddateAsync(nameof(DogRace), result.LastUpdate.Value).ConfigureAwait(false);
|
|
return racesResult.Value.Where(c => c.Deleted == false).OrderBy(c => c.Name).ToList();
|
|
}
|
|
}
|
|
}
|
|
//Keine Daten online, keine offline
|
|
return new List<DogRace>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Hunderasse zurück.
|
|
/// Entweder von der DB oder vom Server
|
|
/// </summary>
|
|
/// <param name="id">Id der Hunderasse</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Hunderasse oder null, wenn nicht gefunden</returns>
|
|
public async Task<DogRace> GetRaceAsync(string id, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var localRace = await Repository.FirstOrDefaultAsync(c => c.Deleted == false && c.Id == id, noTracking: true).ConfigureAwait(false);
|
|
if (localRace == null)
|
|
{
|
|
//Dann wenn lokal nicht verfügbar immer online...
|
|
var isConnected = await _communicationService.IsConnected();
|
|
//isConnected = false;
|
|
if (isConnected)
|
|
{
|
|
var racesResult = await _communicationService.GetDogRaceAsync(id, language, accessToken, token);
|
|
if (racesResult.Success)
|
|
{
|
|
return racesResult.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return localRace;
|
|
}
|
|
|
|
#region Pull-Push Implementation
|
|
|
|
/// <summary>
|
|
/// Holen der Daten vom lokalen Speicher die noch nicht synchronisiert wurden und senden an den Server
|
|
/// </summary>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Task</returns>
|
|
public async Task<SyncResult<DogRace>> PushAsync(string accessToken, CancellationToken token)
|
|
{
|
|
var result = new SyncResult<DogRace>();
|
|
|
|
//Es gibt hier kein Push!
|
|
await Task.Delay(1);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Holen der letzten Daten vom Server und Synchronisieren mit den lokalen Daten
|
|
/// </summary>
|
|
/// <param name="language">Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Task</returns>
|
|
public async Task<SyncResult<DogRace>> PullAsync(string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new SyncResult<DogRace>();
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
|
|
if (isConnected)
|
|
{
|
|
//Zuerst lezte Aktivität holen...
|
|
DateTimeOffset? lastUpdate = null;
|
|
var lastSyncInfo = await _syncInfoPullService.GetAsync(nameof(DogRace));
|
|
if (lastSyncInfo != null)
|
|
lastUpdate = lastSyncInfo.LastUpdate;
|
|
|
|
var ctsQuery = new CancellationTokenSource(Common.Constants.PushPullTimeout);
|
|
var racesResult = await _communicationService.GetDogRacesAsync(lastUpdate, language, accessToken, token);
|
|
if (racesResult.Success)
|
|
{
|
|
result = await HandleChangesAsync(racesResult.Value);
|
|
if (result.LastUpdate != null)
|
|
await _syncInfoPullService.AddOrUpddateAsync(nameof(DogRace), result.LastUpdate.Value).ConfigureAwait(false);
|
|
}
|
|
|
|
result.LastUpdate ??= lastUpdate;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private
|
|
|
|
/// <summary>
|
|
/// Behandeln der Liste von Hunderassen wenn welche vom Online-Store geholt werden.
|
|
/// </summary>
|
|
/// <param name="races">Liste der Hunderassen</param>
|
|
/// <returns>Task</returns>
|
|
private async Task<SyncResult<DogRace>> HandleChangesAsync(List<DogRace> races)
|
|
{
|
|
var result = new SyncResult<DogRace>();
|
|
|
|
//Je Rasse durchgehen ob was gemacht werden soll
|
|
foreach (var race in races)
|
|
{
|
|
var localRace = await Repository.FirstOrDefaultAsync(c => c.Id == race.Id, false);
|
|
if (localRace != null && localRace.UpdatedAt < race.UpdatedAt)
|
|
{
|
|
if (localRace.UpdatedAt >= race.UpdatedAt)
|
|
{
|
|
if (result.LastUpdate == null || result.LastUpdate < localRace.UpdatedAt)
|
|
result.LastUpdate = localRace.UpdatedAt;
|
|
continue;
|
|
}
|
|
|
|
var deleted = localRace.Deleted == false && race.Deleted;
|
|
|
|
localRace.Version = race.Version;
|
|
localRace.UpdatedAt = race.UpdatedAt;
|
|
localRace.Deleted = race.Deleted;
|
|
localRace.Name = race.Name;
|
|
localRace.Description = race.Description;
|
|
localRace.Age = race.Age;
|
|
localRace.SizeAndWeight = race.SizeAndWeight;
|
|
localRace.Personality = race.Personality;
|
|
localRace.Coexistence = race.Coexistence;
|
|
localRace.Care = race.Care;
|
|
localRace.Decision = race.Decision;
|
|
localRace.Photo = race.Photo;
|
|
localRace.Created = race.Created;
|
|
|
|
if (result.LastUpdate == null || result.LastUpdate < localRace.UpdatedAt)
|
|
result.LastUpdate = localRace.UpdatedAt;
|
|
if (!deleted)
|
|
result.Updated.Add(localRace);
|
|
else
|
|
result.Deleted.Add(localRace);
|
|
Repository.Update(localRace);
|
|
}
|
|
|
|
if (localRace == null)
|
|
{
|
|
localRace = new DogRace()
|
|
{
|
|
Id = race.Id,
|
|
Version = race.Version,
|
|
UpdatedAt = race.UpdatedAt,
|
|
Deleted = race.Deleted,
|
|
Name = race.Name,
|
|
Description = race.Description,
|
|
Age = race.Age,
|
|
SizeAndWeight = race.SizeAndWeight,
|
|
Personality = race.Personality,
|
|
Coexistence = race.Coexistence,
|
|
Care = race.Care,
|
|
Decision = race.Decision,
|
|
Photo = race.Photo,
|
|
Created = race.Created
|
|
};
|
|
|
|
Repository.Add(localRace);
|
|
|
|
if (result.LastUpdate == null || result.LastUpdate < localRace.UpdatedAt)
|
|
result.LastUpdate = localRace.UpdatedAt;
|
|
result.Added.Add(localRace);
|
|
}
|
|
}
|
|
|
|
if (result.HasChanges)
|
|
{
|
|
try
|
|
{
|
|
await CommitAsync().ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var err = ex.Message;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|