Skip to content

Commit

Permalink
[#316] Translation Repository - Draft
Browse files Browse the repository at this point in the history
  • Loading branch information
gruenwaldlk committed Oct 12, 2023
1 parent 1027642 commit b36ff21
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 3 deletions.
45 changes: 45 additions & 0 deletions PG.Commons/PG.Commons/Repository/IRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using PG.Commons.Validation;

namespace PG.Commons.Repository;

/// <summary>
/// Base contract for a object storage repository.
/// </summary>
/// <typeparam name="TKey">The key to access values.</typeparam>
/// <typeparam name="TValue">The value.</typeparam>
public interface IRepository<in TKey, TValue> : IValidatable where TValue : IValidatable
{
/// <summary>
/// Tries to insert an object into the repository.
/// </summary>
/// <param name="key">The object's key.</param>
/// <param name="value">the object</param>
/// <returns>True if the insert succeeded, false else.</returns>
bool TryCreate(TKey key, TValue value);

/// <summary>
/// Tries to load the value for a given key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The object to load.</param>
/// <returns>True if the read succeeded, false else.</returns>
bool TryRead(TKey key, out TValue? value);

/// <summary>
/// Tries to update the value for a given key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The object to load.</param>
/// <returns>True if the update succeeded, false else.</returns>
bool TryUpdate(TKey key, TValue value);

/// <summary>
/// Tries to delete a given object from the repository.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>True if the delete succeeded, false else.</returns>
bool TryDelete(TKey key);
}
127 changes: 127 additions & 0 deletions PG.Commons/PG.Commons/Repository/RepositoryBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation.Results;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using PG.Commons.Validation;

namespace PG.Commons.Repository;

/// <inheritdoc />
public abstract class RepositoryBase<TKey, TValue> : IRepository<TKey, TValue>
where TKey : notnull
where TValue :
IValidatable
{
/// <summary>
/// .ctor
/// </summary>
/// <param name="services"></param>
protected RepositoryBase(IServiceProvider services)
{
Logger = services.GetService<ILoggerFactory>()?.CreateLogger(GetType()) ?? NullLogger.Instance;
}

/// <summary>
/// The internal Dictionary.
/// </summary>
protected readonly Dictionary<TKey, TValue> InternalRepository = new();

/// <inheritdoc cref="ILogger{TCategoryName}" />
protected readonly ILogger Logger;

/// <inheritdoc />
public ValidationResult Validate()
{
var errors = new List<ValidationFailure>();
foreach (var validationFailures in InternalRepository.Values.Select(v => v.Validate().Errors))
{
errors.AddRange(validationFailures);
}

return new ValidationResult(errors);
}

/// <inheritdoc />
public void ValidateAndThrow()
{
foreach (var v in InternalRepository.Values)
{
v.ValidateAndThrow();
}
}

/// <inheritdoc />
public bool TryCreate(TKey key, TValue value)
{
if (InternalRepository.ContainsKey(key))
{
Logger.LogInformation(
"The repository already has a value set for the key={key}. The value could not be inserted.", key);
return false;
}

var validationResult = value.Validate();
if (!validationResult.IsValid)
{
Logger.LogWarning("The provided value {value} is invalid. Validation result: {validationResult}", value,
validationResult);
return false;
}

InternalRepository.Add(key, value);
return true;
}

/// <inheritdoc />
public bool TryRead(TKey key, out TValue? value)
{
if (!InternalRepository.ContainsKey(key))
{
Logger.LogInformation("There is no object with key={key} in repository.", key);
value = default;
return false;
}

value = InternalRepository[key];
return true;
}

/// <inheritdoc />
public bool TryUpdate(TKey key, TValue value)
{
if (!InternalRepository.ContainsKey(key))
{
Logger.LogInformation("There is no object with key={key} in repository.", key);
return false;
}

var validationResult = value.Validate();
if (!validationResult.IsValid)
{
Logger.LogWarning("The provided value {value} is invalid. Validation result: {validationResult}", value,
validationResult);
return false;
}

InternalRepository[key] = value;
return true;
}

/// <inheritdoc />
public bool TryDelete(TKey key)
{
if (!InternalRepository.ContainsKey(key))
{
Logger.LogInformation("There is no object with key={key} in repository.", key);
return false;
}

return InternalRepository.Remove(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace PG.StarWarsGame.Localisation.Attributes;
/// <see cref="Attribute" /> that can be used to mark a <see cref="IAlamoLanguageDefinition" /> as the default
/// language.
/// </summary>
public class DefaultLanguageAttribute : Attribute
public sealed class DefaultLanguageAttribute : Attribute
{
/// <summary>
/// Is set to true, if the language is a default.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for details.

using Microsoft.Extensions.DependencyInjection;
using PG.StarWarsGame.Files.DAT;
using PG.StarWarsGame.Localisation.Commons.Helper;

namespace PG.StarWarsGame.Localisation;
Expand All @@ -18,7 +17,7 @@ public static class LocalisationDomain
/// <param name="serviceCollection">The service collection to populate.</param>
public static void RegisterServices(IServiceCollection serviceCollection)
{
DatDomain.RegisterServices(serviceCollection);
PG.StarWarsGame.Files.DAT.DatDomain.RegisterServices(serviceCollection);
serviceCollection
.AddSingleton<IAlamoLanguageDefinitionHelper>(sp => new AlamoLanguageDefinitionHelper(sp))
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<InheritDocEnabled>true</InheritDocEnabled>
</PropertyGroup>
<PropertyGroup>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)Generated</CompilerGeneratedFilesOutputPath>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0-preview.6.23329.7"/>
<PackageReference Include="System.IO.Abstractions" Version="19.2.51"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using PG.Commons.Validation;

namespace PG.StarWarsGame.Localisation.Repository;

/// <summary>
/// A simple translation item.
/// </summary>
public interface ITranslationItem : IValidatable
{
/// <summary>
/// The item's key.
/// </summary>
string Key { get; }

/// <summary>
/// The item's value.
/// </summary>
string Value { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using PG.Commons.Repository;
using PG.StarWarsGame.Localisation.Languages;

namespace PG.StarWarsGame.Localisation.Repository;

/// <summary>
/// A repository to hold <see cref="ITranslationItem" />s.
/// </summary>
public interface ITranslationItemRepository : IRepository<IAlamoLanguageDefinition, ITranslationItem>
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using PG.Commons.Repository;

namespace PG.StarWarsGame.Localisation.Repository;

/// <summary>
/// Repository for sorted localisations.
/// </summary>
public interface ITranslationRepository : IRepository<string, ITranslationItemRepository>
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using System;
using FluentValidation;
using FluentValidation.Results;

namespace PG.StarWarsGame.Localisation.Repository;

/// <inheritdoc cref="ITranslationItem" />
public sealed class TranslationItem : ITranslationItem
{
internal TranslationItem()
{
}

/// <summary>
/// .ctor
/// </summary>
/// <param name="key">The string key.</param>
/// <param name="value">The translated text.</param>
/// <exception cref="ArgumentNullException"></exception>
internal TranslationItem(string key, string value)
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentNullException(nameof(key));
}

if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentNullException(nameof(value));
}

Key = key ?? throw new ArgumentNullException(nameof(key));
Value = value ?? throw new ArgumentNullException(nameof(value));
}


/// <inheritdoc />
public string Key { get; private set; } = null!;

/// <inheritdoc />
public string Value { get; private set; } = null!;

/// <inheritdoc />
public ValidationResult Validate()
{
return new TranslationItemValidator().Validate(this);
}

/// <inheritdoc />
public void ValidateAndThrow()
{
new TranslationItemValidator().ValidateAndThrow(this);
}

/// <inheritdoc />
private class TranslationItemValidator : AbstractValidator<TranslationItem>
{
internal TranslationItemValidator()
{
RuleFor(i => i.Key).NotNull().NotEmpty();
RuleFor(i => i.Value).NotNull().NotEmpty();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using System;
using PG.Commons.Repository;
using PG.StarWarsGame.Localisation.Languages;

namespace PG.StarWarsGame.Localisation.Repository;

/// <inheritdoc cref="ITranslationItemRepository" />
internal sealed class TranslationItemRepository : RepositoryBase<IAlamoLanguageDefinition, ITranslationItem>,
ITranslationItemRepository
{
/// <inheritdoc />
public TranslationItemRepository(IServiceProvider services) : base(services)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using System;
using PG.Commons.Repository;

namespace PG.StarWarsGame.Localisation.Repository;

internal sealed class TranslationRepository : RepositoryBase<string, ITranslationItemRepository>, ITranslationRepository
{
/// <inheritdoc />
public TranslationRepository(IServiceProvider services) : base(services)
{
}
}

0 comments on commit b36ff21

Please sign in to comment.