Initial commit

This commit is contained in:
2021-06-15 10:59:47 +02:00
commit 8e156ba356
65 changed files with 1786 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
namespace GerstITS.Examples.Logic.Example
{
public class Example
{
#region Properties
public string FirstName { get; set; }
public string LastName { get; set; }
public string Description { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,8 @@
namespace GerstITS.Examples.Logic.Example
{
public interface IExampleProvider
{
Example GetById(int id);
Example GetById_v1_1(int id);
}
}

View File

@@ -0,0 +1,51 @@
using AutoMapper;
using GerstITS.Data;
namespace GerstITS.Examples.Logic.Example
{
internal sealed class ExampleProvider : IExampleProvider
{
#region Fields
private readonly IMapper _mapper;
#endregion
#region Constructors
public ExampleProvider(IMapper mapper)
{
_mapper = mapper;
}
#endregion
#region IExampleProvider
public Example GetById(int id)
{
ThrowsAnExceptionIfEntityIsNotFound(id);
return _mapper.Map<Example>(id);
}
public Example GetById_v1_1(int id)
{
ThrowsAnExceptionIfEntityIsNotFound(id);
return _mapper.Map<Example>(id);
}
#endregion
#region Methods
private static void ThrowsAnExceptionIfEntityIsNotFound(int id)
{
if (id % 2 == 0)
throw new EntityNotFoundException($"Example mit der Id '{id}' nicht gefunden.");
}
#endregion
}
}

View File

@@ -0,0 +1,19 @@
using AutoMapper;
namespace GerstITS.Examples.Logic.Example
{
internal sealed class IntegerMapping : Profile
{
#region Construtcors
public IntegerMapping()
{
CreateMap<int, Example>()
.ForMember(x => x.FirstName, m => m.MapFrom((s,t) => $"First Name {s}"))
.ForMember(x => x.LastName, m => m.MapFrom((s,t) => $"Last Name {s}"))
.ForMember(x => x.Description, m => m.MapFrom((s,t) => $"Useful description for id '{s}'"));
}
#endregion
}
}

View File

@@ -0,0 +1,54 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Company>ITSCare GbR</Company>
<Authors>ITSCare GbR</Authors>
<Copyright>Copyright © ITSCare GbR 2021</Copyright>
<Product>ITSCare GbR Example Logic</Product>
<Version>0.0.0.0</Version>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
<AssemblyInformationalVersion>0.0.0.0</AssemblyInformationalVersion>
<FileVersion>0.0.0.0</FileVersion>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<WarningsAsErrors />
<NoWarn />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<WarningsAsErrors />
<NoWarn />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="FluentValidation" Version="10.2.3" />
<PackageReference Include="GerstITS.AutoMapper" Version="2021.6.17" />
<PackageReference Include="GerstITS.Data" Version="2021.6.17" />
<PackageReference Include="GerstITS.IoC" Version="2021.6.17" />
<PackageReference Include="GerstITS.IoC.DotNetCore" Version="2021.6.17" />
<PackageReference Include="GerstITS.Search" Version="2021.6.17" />
<PackageReference Include="GerstITS.Validation" Version="2021.6.17" />
<PackageReference Include="GerstITS.Web.Api" Version="2021.6.17" />
</ItemGroup>
<ItemGroup>
<Compile Update="Module.Example.cs">
<DependentUpon>Module.cs</DependentUpon>
</Compile>
<Compile Update="Module.Shared.cs">
<DependentUpon>Module.cs</DependentUpon>
</Compile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=country_005Ccontracts/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=country_005Cmapping/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=country_005Csearch/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=country_005Csearch_005Cextensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=country_005Csearch_005Crules/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=country_005Cvalidations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=example_005Ccontracts/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=example_005Cextensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=example_005Cmappings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=example_005Cvalidations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=shared_005Cbases/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=shared_005Cextensions/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -0,0 +1,20 @@
using GerstITS.AutoMapper;
using GerstITS.Examples.Logic.Example;
using Microsoft.Extensions.DependencyInjection;
namespace GerstITS.Examples.Logic
{
public sealed partial class Module
{
#region Methods
private static void RegisterExample(IServiceCollection container)
{
container.RegisterMappingsOf<IExampleProvider>();
container.AddScoped<IExampleProvider, ExampleProvider>();
}
#endregion
}
}

View File

@@ -0,0 +1,22 @@
using GerstITS.Examples.Logic.Shared.Search.Sorting;
using GerstITS.Examples.Logic.Shared.Validation;
using GerstITS.Search;
using GerstITS.Validation;
using Microsoft.Extensions.DependencyInjection;
namespace GerstITS.Examples.Logic
{
public sealed partial class Module
{
#region Methods
private static void RegisterShared(IServiceCollection container)
{
container.RegisterValidationRulesOf<IdValidationRule>();
container.AddScoped<ISortingProvider, SortingProvider>();
}
#endregion
}
}

View File

@@ -0,0 +1,18 @@
using GerstITS.IoC;
using Microsoft.Extensions.DependencyInjection;
namespace GerstITS.Examples.Logic
{
public sealed partial class Module : IIoCModule<IServiceCollection>
{
#region IIoCModule
public void RegisterComponents(IServiceCollection container)
{
RegisterExample(container);
RegisterShared(container);
}
#endregion
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using GerstITS.Common;
using GerstITS.Data;
namespace GerstITS.Examples.Logic.Shared
{
internal static class ISearchEngineExtensions
{
#region Methods
public static TEntity QueryBy<TEntity>(this IReadOnlyRepository repository, Expression<Func<TEntity, bool>> condition)
where TEntity : IEntity
{
return repository.Query<TEntity>()
.Where(condition)
.FirstOrDefault();
}
public static TModel ThrowsAnExceptionIfNotFound<TModel, TKey>(this TModel model, TKey id)
{
if (model.IsNull())
throw new EntityNotFoundException($"{typeof(TModel).Name} with id '{id}' not found.");
return model;
}
#endregion
}
}

View File

@@ -0,0 +1,6 @@
namespace GerstITS.Examples.Logic.Shared.Search.Sorting
{
internal interface ISortable
{
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using GerstITS.Common;
using GerstITS.Search;
namespace GerstITS.Examples.Logic.Shared.Search.Sorting
{
internal class SortingProvider : ISortingProvider
{
#region ISortingProvider
public bool CanSort<TItem>(IQueryable<TItem> query)
{
return typeof(TItem).IsAssignableTo(typeof(ISortable));
}
public IQueryable<TItem> Sort<TItem>(IQueryable<TItem> query, ISorting sorting)
{
var propertyInfo = typeof(TItem).GetProperties()
.SingleOrDefault(i => string.Equals(i.Name, sorting.SortBy, StringComparison.InvariantCultureIgnoreCase));
if (!CanSort(query) || propertyInfo.IsNull())
return query;
var sortExpression = CreateSortExpression<TItem>(propertyInfo);
return (sorting.SortDirection == SortingDirections.Ascending
? query.OrderBy(sortExpression)
: query.OrderByDescending(sortExpression))
.AsQueryable();
}
#endregion
#region Methods
private static Expression<Func<TItem, object>> CreateSortExpression<TItem>(MemberInfo propertyInfo)
{
var parameterExpression = Expression.Parameter(typeof(TItem), "x");
var propertyExpression = Expression.Property(parameterExpression, propertyInfo.Name);
var convertExpression = Expression.Convert(propertyExpression, typeof(object));
return Expression.Lambda<Func<TItem, object>>(convertExpression, parameterExpression);
}
#endregion
}
}

View File

@@ -0,0 +1,19 @@
using FluentValidation;
using GerstITS.Validation;
namespace GerstITS.Examples.Logic.Shared.Validation
{
internal sealed class IdValidationRule : ValidationRuleBase<int>
{
#region Constructors
public IdValidationRule()
{
RuleFor(x => x)
.GreaterThan(0)
.OverridePropertyName("id");
}
#endregion
}
}