🎉 first push

pull/10/head
Marc CHEVALDONNE 2 years ago
parent ac6dba3bf5
commit 7c8fa848e3

@ -1,2 +1,168 @@
# EntityFramework_LoL # prepaLoL
## Diagramme de classes du modèle
```mermaid
classDiagram
class LargeImage{
+/Base64 : string
}
class Champion{
+/Name : string
+/Bio : string
+/Icon : string
+/Characteristics : Dictionary~string, int~
~ AddSkin(skin : Skin) bool
~ RemoveSkin(skin: Skin) bool
+ AddSkill(skill: Skill) bool
+ RemoveSkill(skill: Skill) bool
+ AddCharacteristics(someCharacteristics : params Tuple~string, int~[])
+ RemoveCharacteristics(label : string) bool
+ this~label : string~ : int?
}
Champion --> "1" LargeImage : Image
class ChampionClass{
<<enumeration>>
Unknown,
Assassin,
Fighter,
Mage,
Marksman,
Support,
Tank,
}
Champion --> "1" ChampionClass : Class
class Skin{
+/Name : string
+/Description : string
+/Icon : string
+/Price : float
}
Skin --> "1" LargeImage : Image
Champion "1" -- "*" Skin
class Skill{
+/Name : string
+/Description : string
}
class SkillType{
<<enumeration>>
Unknown,
Basic,
Passive,
Ultimate,
}
Skill --> "1" SkillType : Type
Champion --> "*" Skill
class Rune{
+/Name : string
+/Description : string
}
Rune --> "1" LargeImage : Image
class RuneFamily{
<<enumeration>>
Unknown,
Precision,
Domination
}
Rune --> "1" RuneFamily : Family
class Category{
<<enumeration>>
Major,
Minor1,
Minor2,
Minor3,
OtherMinor1,
OtherMinor2
}
class RunePage{
+/Name : string
+/this[category : Category] : Rune?
- CheckRunes(newRuneCategory : Category)
- CheckFamilies(cat1 : Category, cat2 : Category) bool?
- UpdateMajorFamily(minor : Category, expectedValue : bool)
}
RunePage --> "*" Rune : Dictionary~Category,Rune~
```
## Diagramme de classes des interfaces de gestion de l'accès aux données
```mermaid
classDiagram
direction LR;
class IGenericDataManager~T~{
<<interface>>
GetNbItems() Task~int~
GetItems(index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~
GetNbItemsByName(substring : string)
GetItemsByName(substring : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~
UpdateItem(oldItem : T, newItem : T) Task~T~~
AddItem(item : T) Task~T~
DeleteItem(item : T) Task~bool~
}
class IChampionsManager{
<<interface>>
GetNbItemsByCharacteristic(charName : string)
GetItemsByCharacteristic(charName : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsByClass(championClass : ChampionClass)
GetItemsByClass(championClass : ChampionClass, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsBySkill(skill : Skill?)
GetItemsBySkill(skill : Skill?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsBySkill(skill : string)
GetItemsBySkill(skill : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
GetNbItemsByRunePage(runePage : RunePage?)
GetItemsByRunePage(runePage : RunePage?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~
}
class ISkinsManager{
<<interface>>
GetNbItemsByChampion(champion : Champion?)
GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Skin?~~
}
class IRunesManager{
<<interface>>
GetNbItemsByFamily(family : RuneFamily)
GetItemsByFamily(family : RuneFamily, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Rune?~~
}
class IRunePagesManager{
<<interface>>
GetNbItemsByRune(rune : Rune?)
GetItemsByRune(rune : Rune?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~
GetNbItemsByChampion(champion : Champion?)
GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~
}
IGenericDataManager~Champion?~ <|.. IChampionsManager : T--Champion?
IGenericDataManager~Skin?~ <|.. ISkinsManager : T--Skin?
IGenericDataManager~Rune?~ <|.. IRunesManager : T--Rune?
IGenericDataManager~RunePage?~ <|.. IRunePagesManager : T--RunePage?
class IDataManager{
<<interface>>
}
IChampionsManager <-- IDataManager : ChampionsMgr
ISkinsManager <-- IDataManager : SkinsMgr
IRunesManager <-- IDataManager : RunesMgr
IRunePagesManager <-- IDataManager : RunePagesMgr
```
## Diagramme de classes simplifié du Stub
```mermaid
classDiagram
direction TB;
IDataManager <|.. StubData
ChampionsManager ..|> IChampionsManager
StubData --> ChampionsManager
RunesManager ..|> IRunesManager
StubData --> RunesManager
RunePagesManager ..|> IRunePagesManager
StubData --> RunePagesManager
SkinsManager ..|> ISkinsManager
StubData --> SkinsManager
StubData --> RunesManager
StubData --> "*" Champion
StubData --> "*" Rune
StubData --> "*" RunePages
StubData --> "*" Skins
```

@ -0,0 +1,51 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 25.0.1704.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C76D0C23-1FFA-4963-93CD-E12BD643F030}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTests", "Tests\ConsoleTests\ConsoleTests.csproj", "{1889FA6E-B7C6-416E-8628-9449FB9070B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{3B720C0C-53FE-4642-A2DB-87FD8634CD74}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stub", "Stub", "{2C607793-B163-4731-A4D1-AFE8A7C4C170}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StubLib", "StubLib\StubLib.csproj", "{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2960F9BA-49DE-494D-92E3-CE5A794BA1A9}.Release|Any CPU.Build.0 = Release|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1889FA6E-B7C6-416E-8628-9449FB9070B9}.Release|Any CPU.Build.0 = Release|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B720C0C-53FE-4642-A2DB-87FD8634CD74}.Release|Any CPU.Build.0 = Release|Any CPU
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {92F3083D-793F-4552-8A9A-0AD6534159C9}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1889FA6E-B7C6-416E-8628-9449FB9070B9} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB} = {2C607793-B163-4731-A4D1-AFE8A7C4C170}
EndGlobalSection
EndGlobal

@ -0,0 +1,151 @@
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Numerics;
using System.Text;
namespace Model;
public class Champion : IEquatable<Champion>
{
public string Name
{
get => name;
private init
{
if(string.IsNullOrWhiteSpace(value))
{
name = "Unknown";
return;
}
name = value;
}
}
private readonly string name = null!;
public string Bio
{
get => bio;
set
{
if(value == null)
{
bio = "";
return;
}
bio = value;
}
}
private string bio = "";
public ChampionClass Class { get; set; }
public string Icon { get; set; }
public LargeImage Image { get; set; }
public Champion(string name, ChampionClass champClass = ChampionClass.Unknown, string icon = "", string image = "", string bio = "")
{
Name = name;
Class = champClass;
Icon = icon;
Image = new LargeImage(image);
Bio = bio;
Characteristics = new ReadOnlyDictionary<string, int>(characteristics);
Skins = new ReadOnlyCollection<Skin>(skins);
}
public ReadOnlyCollection<Skin> Skins { get; private set; }
private List<Skin> skins = new ();
public ReadOnlyDictionary<string, int> Characteristics { get; private set; }
private readonly Dictionary<string, int> characteristics = new Dictionary<string, int>();
public ImmutableHashSet<Skill> Skills => skills.ToImmutableHashSet();
private HashSet<Skill> skills = new HashSet<Skill>();
internal bool AddSkin(Skin skin)
{
if (skins.Contains(skin))
return false;
skins.Add(skin);
return true;
}
internal bool RemoveSkin(Skin skin)
=> skins.Remove(skin);
public bool AddSkill(Skill skill)
=> skills.Add(skill);
public bool RemoveSkill(Skill skill)
=> skills.Remove(skill);
public void AddCharacteristics(params Tuple<string, int>[] someCharacteristics)
{
foreach(var c in someCharacteristics)
{
characteristics[c.Item1] = c.Item2;
}
}
public bool RemoveCharacteristics(string label)
=> characteristics.Remove(label);
public int? this[string label]
{
get
{
if(!characteristics.TryGetValue(label, out int value)) return null;
else return value;
}
set
{
if(!value.HasValue)
{
RemoveCharacteristics(label);
return;
}
characteristics[label] = value.Value;
}
}
public override bool Equals(object? obj)
{
if(ReferenceEquals(obj, null)) return false;
if(ReferenceEquals(obj, this)) return true;
if(GetType() != obj.GetType()) return false;
return Equals(obj as Champion);
}
public override int GetHashCode()
=> Name.GetHashCode() % 997;
public bool Equals(Champion? other)
=> Name.Equals(other?.Name);
public override string ToString()
{
StringBuilder sb = new StringBuilder($"{Name} ({Class})");
if(!string.IsNullOrWhiteSpace(bio))
{
sb.AppendLine($"\t{bio}");
}
if(characteristics.Any())
{
sb.AppendLine("\tCharacteristics:");
foreach(var characteristic in characteristics)
{
sb.AppendLine($"\t\t{characteristic.Key} - {characteristic.Value}");
}
}
if(skills.Any())
{
sb.AppendLine("\tSkills:");
foreach(var skill in Skills)
{
sb.AppendLine($"\t\t{skill.Name} - {skill.Description}");
}
}
return sb.ToString();
}
}

@ -0,0 +1,53 @@
using System;
using Shared;
namespace Model
{
public interface IDataManager
{
IChampionsManager ChampionsMgr { get; }
ISkinsManager SkinsMgr { get; }
IRunesManager RunesMgr { get; }
IRunePagesManager RunePagesMgr { get; }
}
public interface IChampionsManager : IGenericDataManager<Champion?>
{
Task<int> GetNbItemsByCharacteristic(string charName);
Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<int> GetNbItemsByClass(ChampionClass championClass);
Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<int> GetNbItemsBySkill(Skill? skill);
Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<int> GetNbItemsByRunePage(RunePage? runePage);
Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<int> GetNbItemsBySkill(string skill);
Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false);
}
public interface ISkinsManager : IGenericDataManager<Skin?>
{
Task<int> GetNbItemsByChampion(Champion? champion);
Task<IEnumerable<Skin?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false);
}
public interface IRunesManager : IGenericDataManager<Rune?>
{
Task<int> GetNbItemsByFamily(RuneFamily family);
Task<IEnumerable<Rune?>> GetItemsByFamily(RuneFamily family, int index, int count, string? orderingPropertyName = null, bool descending = false);
}
public interface IRunePagesManager : IGenericDataManager<RunePage?>
{
Task<int> GetNbItemsByRune(Rune? rune);
Task<IEnumerable<RunePage?>> GetItemsByRune(Rune? rune, int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<int> GetNbItemsByChampion(Champion? champion);
Task<IEnumerable<RunePage?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false);
}
}

@ -0,0 +1,28 @@
using System;
namespace Model
{
public class LargeImage : IEquatable<LargeImage>
{
public string Base64 { get; set; }
public LargeImage(string base64)
{
Base64 = base64;
}
public bool Equals(LargeImage? other)
=> other != null && other.Base64.Equals(Base64);
public override bool Equals(object? obj)
{
if(ReferenceEquals(obj, null)) return false;
if(ReferenceEquals(obj!, this)) return true;
if(GetType() != obj!.GetType()) return false;
return Equals(obj! as LargeImage);
}
public override int GetHashCode()
=> Base64.Substring(0, 10).GetHashCode();
}
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="enums\" />
</ItemGroup>
<ItemGroup>
<Folder Include="enums\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,69 @@
using System;
namespace Model
{
public class Rune : IEquatable<Rune>
{
public string Name
{
get => name;
private init
{
if(string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("a Rune must have a name");
}
name = value;
}
}
private readonly string name = null!;
public string Description
{
get => description;
set
{
if(string.IsNullOrWhiteSpace(value))
{
description = "";
return;
}
description = value;
}
}
private string description = "";
public RuneFamily Family { get; set; }
public string Icon { get; set; }
public LargeImage Image { get; set; }
public Rune(string name, RuneFamily family, string icon = "", string image = "", string description = "")
{
Name = name;
Family = family;
Icon = icon;
Image = new LargeImage(image);
Description = description;
}
public override bool Equals(object? obj)
{
if(ReferenceEquals(obj, null)) return false;
if(ReferenceEquals(obj, this)) return true;
if(GetType() != obj.GetType()) return false;
return Equals(obj as Rune);
}
public bool Equals(Rune? other)
=> Name.Equals(other?.Name);
public override int GetHashCode()
=> Name.GetHashCode() % 281;
public override string ToString()
=> $"{Name} ({Family})";
}
}

@ -0,0 +1,17 @@
using System;
namespace Model
{
public partial class RunePage
{
public enum Category
{
Major,
Minor1,
Minor2,
Minor3,
OtherMinor1,
OtherMinor2
}
}
}

@ -0,0 +1,95 @@
using System;
using System.Collections.ObjectModel;
namespace Model
{
public partial class RunePage
{
public string Name
{
get => name;
private init
{
if(string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("a Rune Page must have a name");
}
name = value;
}
}
private readonly string name = null!;
public ReadOnlyDictionary<Category, Rune> Runes { get; private set; }
private Dictionary<Category, Rune> runes = new Dictionary<Category, Rune>();
public RunePage(string name)
{
Name = name;
Runes = new ReadOnlyDictionary<Category, Rune>(runes);
}
public Rune? this[Category category]
{
get
{
if(runes.TryGetValue(category, out Rune? rune))
{
return rune;
}
return null;
}
set
{
if(value == null)
{
runes.Remove(category);
}
runes[category] = value!;
CheckRunes(category);
}
}
private void CheckRunes(Category newRuneCategory)
{
switch(newRuneCategory)
{
case Category.Major:
UpdateMajorFamily(Category.Minor1, true);
UpdateMajorFamily(Category.Minor2, true);
UpdateMajorFamily(Category.Minor3, true);
UpdateMajorFamily(Category.OtherMinor1, false);
UpdateMajorFamily(Category.OtherMinor2, false);
break;
case Category.Minor1:
case Category.Minor2:
case Category.Minor3:
UpdateMajorFamily(newRuneCategory, true);
break;
case Category.OtherMinor1:
case Category.OtherMinor2:
UpdateMajorFamily(newRuneCategory, false);
break;
}
}
private bool? CheckFamilies(Category cat1, Category cat2)
{
runes.TryGetValue(cat1, out Rune? rune1);
runes.TryGetValue(cat2, out Rune? rune2);
if(rune1 == null || rune2 == null)
{
return null;
}
return rune1.Family == rune2.Family;
}
private void UpdateMajorFamily(Category minor, bool expectedValue)
{
if(CheckFamilies(Category.Major, minor).GetValueOrDefault(expectedValue) == expectedValue)
{
runes.Remove(minor);
}
}
}
}

@ -0,0 +1,63 @@
using System;
namespace Model
{
public class Skill : IEquatable<Skill>
{
public SkillType Type { get; private set; }
public string Name
{
get => name;
private init
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("a Skill needs a name");
}
name = value;
}
}
private readonly string name = null!;
public string Description
{
get => description;
set
{
if(string.IsNullOrWhiteSpace(value))
{
description = "";
return;
}
description = value;
}
}
private string description = "";
public Skill(string name, SkillType type, string description = "")
{
Name = name;
Type = type;
Description = description ?? "";
}
public override bool Equals(object? obj)
{
if(ReferenceEquals(obj, null)) return false;
if(ReferenceEquals(obj, this)) return true;
if(GetType() != obj.GetType()) return false;
return Equals(obj as Skill);
}
public bool Equals(Skill? other)
=> Name.Equals(other?.Name) && Type == other.Type;
public override int GetHashCode()
=> Name.GetHashCode() % 281;
public override string ToString()
=> $"{Name} ({Type})";
}
}

@ -0,0 +1,83 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace Model
{
public class Skin : IEquatable<Skin>
{
public string Name
{
get => name;
private init
{
if(string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("A skin must have a name");
}
name = value;
}
}
private readonly string name = null!;
public string Description
{
get => description;
set
{
if (string.IsNullOrWhiteSpace(value))
{
description = "";
return;
}
description = value;
}
}
private string description = "";
public string Icon { get; set; }
public LargeImage Image { get; set; }
public float Price { get; set; }
public Champion Champion
{
get => champion;
private init
{
if (value == null)
throw new ArgumentNullException("A skill can't have a null champion");
champion = value;
}
}
private readonly Champion champion = null!;
public Skin(string name, Champion champion, float price = 0.0f, string icon = "", string image = "", string description = "")
{
Name = name;
Champion = champion;
Champion.AddSkin(this);
Price = price;
Icon = icon;
Image = new LargeImage(image);
Description = description;
}
public override bool Equals(object? obj)
{
if(ReferenceEquals(obj, null)) return false;
if(ReferenceEquals(obj, this)) return true;
if(GetType() != obj.GetType()) return false;
return Equals(obj as Skin);
}
public bool Equals(Skin? other)
=> Name.Equals(other?.Name);
public override int GetHashCode()
=> Name.GetHashCode() % 997;
public override string ToString()
=> $"{Name}";
}
}

@ -0,0 +1,15 @@
using System;
namespace Model
{
public enum ChampionClass
{
Unknown,
Assassin,
Fighter,
Mage,
Marksman,
Support,
Tank,
}
}

@ -0,0 +1,11 @@
using System;
namespace Model
{
public enum RuneFamily
{
Unknown,
Precision,
Domination
}
}

@ -0,0 +1,12 @@
using System;
namespace Model
{
public enum SkillType
{
Unknown,
Basic,
Passive,
Ultimate
}
}

@ -0,0 +1,11 @@
namespace Shared;
public interface IGenericDataManager<T>
{
Task<int> GetNbItems();
Task<IEnumerable<T>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<int> GetNbItemsByName(string substring);
Task<IEnumerable<T>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false);
Task<T> UpdateItem(T oldItem, T newItem);
Task<T> AddItem(T item);
Task<bool> DeleteItem(T item);
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -0,0 +1,65 @@
using System;
using Model;
namespace StubLib
{
static class Extensions
{
internal static Task<IEnumerable<T?>> GetItemsWithFilterAndOrdering<T>(this IEnumerable<T> collection,
Func<T, bool> filter, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
IEnumerable<T> temp = collection;
temp = temp.Where(item => filter(item));
if(orderingPropertyName != null)
{
var prop = typeof(T).GetProperty(orderingPropertyName!);
if (prop != null)
{
temp = descending ? temp.OrderByDescending(item => prop.GetValue(item))
: temp.OrderBy(item => prop.GetValue(item));
}
}
return Task.FromResult<IEnumerable<T?>>(temp.Skip(index*count).Take(count));
}
internal static Task<int> GetNbItemsWithFilter<T>(this IEnumerable<T> collection, Func<T, bool> filter)
{
return Task.FromResult(collection.Count(item => filter(item)));
}
internal static Task<T?> AddItem<T>(this IList<T> collection, T? item)
{
if(item == null || collection.Contains(item))
{
return Task.FromResult<T?>(default(T));
}
collection.Add(item);
return Task.FromResult<T?>(item);
}
internal static Task<bool> DeleteItem<T>(this IList<T> collection, T? item)
{
if(item == null)
{
return Task.FromResult(false);
}
bool result = collection.Remove(item!);
return Task.FromResult(result);
}
internal static Task<T?> UpdateItem<T>(this IList<T> collection, T? oldItem, T? newItem)
{
if(oldItem == null || newItem == null) return Task.FromResult<T?>(default(T));
if(!collection.Contains(oldItem))
{
return Task.FromResult<T?>(default(T));
}
collection.Remove(oldItem!);
collection.Add(newItem!);
return Task.FromResult<T?>(newItem);
}
}
}

@ -0,0 +1,100 @@
using System;
using Model;
namespace StubLib
{
public partial class StubData
{
private List<Champion> champions = new()
{
new Champion("Akali", ChampionClass.Assassin),
new Champion("Aatrox", ChampionClass.Fighter),
new Champion("Ahri", ChampionClass.Mage),
new Champion("Akshan", ChampionClass.Marksman),
new Champion("Bard", ChampionClass.Support),
new Champion("Alistar", ChampionClass.Tank),
};
public class ChampionsManager : IChampionsManager
{
private readonly StubData parent;
public ChampionsManager(StubData parent)
=> this.parent = parent;
public Task<Champion?> AddItem(Champion? item)
=> parent.champions.AddItem(item);
public Task<bool> DeleteItem(Champion? item)
=> parent.champions.DeleteItem(item);
public Task<int> GetNbItems()
=> Task.FromResult(parent.champions.Count);
public Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.champions.GetItemsWithFilterAndOrdering(
c => true,
index, count,
orderingPropertyName, descending);
private Func<Champion, string, bool> filterByCharacteristic = (champ, charName) => champ.Characteristics.Keys.Any(k => k.Contains(charName, StringComparison.InvariantCultureIgnoreCase));
public Task<int> GetNbItemsByCharacteristic(string charName)
=> parent.champions.GetNbItemsWithFilter(champ => filterByCharacteristic(champ, charName));
public Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.champions.GetItemsWithFilterAndOrdering(
champ => filterByCharacteristic(champ, charName),
index, count, orderingPropertyName, descending);
private Func<Champion, ChampionClass, bool> filterByClass = (champ, championClass) => champ.Class == championClass;
public Task<int> GetNbItemsByClass(ChampionClass championClass)
=> parent.champions.GetNbItemsWithFilter(
champ => filterByClass(champ, championClass));
public Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName, bool descending = false)
=> parent.champions.GetItemsWithFilterAndOrdering(
champ => filterByClass(champ, championClass),
index, count, orderingPropertyName, descending);
private Func<Champion, Skill?, bool> filterBySkill = (champ, skill) => skill != null && champ.Skills.Contains(skill!);
public Task<int> GetNbItemsBySkill(Skill? skill)
=> parent.champions.GetNbItemsWithFilter(champ => filterBySkill(champ, skill));
public Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.champions.GetItemsWithFilterAndOrdering(champ => filterBySkill(champ, skill), index, count, orderingPropertyName, descending);
private static Func<Champion, string, bool> filterBySkillSubstring = (champ, skill) => champ.Skills.Any(s => s.Name.Contains(skill, StringComparison.InvariantCultureIgnoreCase));
public Task<int> GetNbItemsBySkill(string skillSubstring)
=> parent.champions.GetNbItemsWithFilter(champ => filterBySkillSubstring(champ, skillSubstring));
public Task<IEnumerable<Champion?>> GetItemsBySkill(string skillSubstring, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.champions.GetItemsWithFilterAndOrdering(champ => filterBySkillSubstring(champ, skillSubstring), index, count, orderingPropertyName, descending);
public Task<int> GetNbItemsByRunePage(RunePage? runePage)
=> Task.FromResult(parent.championsAndRunePages.Count(tuple => tuple.Item2.Equals(runePage)));
public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> Task.FromResult<IEnumerable<Champion?>>
(parent.championsAndRunePages
.Where(tuple => tuple.Item2.Equals(runePage))
.Select(tuple => tuple.Item1)
.Skip(index*count).Take(count));
private Func<Champion, string, bool> filterByName = (champ, substring) => champ.Name.Contains(substring, StringComparison.InvariantCultureIgnoreCase);
public Task<int> GetNbItemsByName(string substring)
=> parent.champions.GetNbItemsWithFilter(champ => filterByName(champ, substring));
public Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName, bool descending = false)
=> parent.champions.GetItemsWithFilterAndOrdering(champ => filterByName(champ, substring), index, count, orderingPropertyName, descending);
public Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
=> parent.champions.UpdateItem(oldItem, newItem);
}
}
}

@ -0,0 +1,83 @@
using System;
using Model;
namespace StubLib
{
public partial class StubData
{
private readonly List<RunePage> runePages = new();
private void InitRunePages()
{
var runePage1 = new RunePage("rune page 1");
runePage1[RunePage.Category.Major] = runes[0];
runePage1[RunePage.Category.Minor1] = runes[1];
runePage1[RunePage.Category.Minor2] = runes[2];
runePage1[RunePage.Category.Minor3] = runes[3];
runePage1[RunePage.Category.OtherMinor1] = runes[4];
runePage1[RunePage.Category.OtherMinor2] = runes[5];
runePages.Add(runePage1);
}
public class RunePagesManager : IRunePagesManager
{
private readonly StubData parent;
public RunePagesManager(StubData parent)
=> this.parent = parent;
private static Func<RunePage, string, bool> filterByName
= (rp, substring) => rp.Name.Contains(substring, StringComparison.InvariantCultureIgnoreCase);
private static Func<RunePage, Rune?, bool> filterByRune
= (rp, rune) => rune != null && rp.Runes.Values.Contains(rune!);
public Task<RunePage?> AddItem(RunePage? item)
=> parent.runePages.AddItem(item);
public Task<bool> DeleteItem(RunePage? item)
=> parent.runePages.DeleteItem(item);
public Task<IEnumerable<RunePage?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.runePages.GetItemsWithFilterAndOrdering(
rp => true,
index, count, orderingPropertyName, descending);
public Task<IEnumerable<RunePage?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> Task.FromResult<IEnumerable<RunePage?>>(
parent.championsAndRunePages
.Where(tuple => tuple.Item1.Equals(champion))
.Select(tuple => tuple.Item2)
.Skip(index*count).Take(count));
public Task<IEnumerable<RunePage?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.runePages.GetItemsWithFilterAndOrdering(
rp => filterByName(rp, substring),
index, count, orderingPropertyName, descending);
public Task<IEnumerable<RunePage?>> GetItemsByRune(Rune? rune, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.runePages.GetItemsWithFilterAndOrdering(
rp => filterByRune(rp, rune),
index, count, orderingPropertyName, descending);
public Task<int> GetNbItems()
=> parent.runePages.GetNbItemsWithFilter(
rp => true);
public Task<int> GetNbItemsByChampion(Champion? champion)
=> Task.FromResult(parent.championsAndRunePages.Count(tuple => tuple.Item1.Equals(champion)));
public Task<int> GetNbItemsByName(string substring)
=> parent.runePages.GetNbItemsWithFilter(
rp => filterByName(rp, substring));
public Task<int> GetNbItemsByRune(Rune? rune)
=> parent.runePages.GetNbItemsWithFilter(
rp => filterByRune(rp, rune));
public Task<RunePage?> UpdateItem(RunePage? oldItem, RunePage? newItem)
=> parent.runePages.UpdateItem(oldItem, newItem);
}
}
}

@ -0,0 +1,69 @@
using System;
using Model;
namespace StubLib
{
public partial class StubData
{
private readonly List<Rune> runes = new()
{
new Rune("Conqueror", RuneFamily.Precision),
new Rune("Triumph", RuneFamily.Precision),
new Rune("Legend: Alacrity", RuneFamily.Precision),
new Rune("Legend: Tenacity", RuneFamily.Precision),
new Rune("last stand", RuneFamily.Domination),
new Rune("last stand 2", RuneFamily.Domination),
};
public class RunesManager : IRunesManager
{
private readonly StubData parent;
public RunesManager(StubData parent)
=> this.parent = parent;
public Task<Rune?> AddItem(Rune? item)
=> parent.runes.AddItem(item);
public Task<bool> DeleteItem(Rune? item)
=> parent.runes.DeleteItem(item);
public Task<IEnumerable<Rune?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.runes.GetItemsWithFilterAndOrdering(
r => true,
index, count, orderingPropertyName, descending);
private static Func<Rune, RuneFamily, bool> filterByRuneFamily
= (rune, family) => rune.Family == family;
private static Func<Rune, string, bool> filterByName
= (rune, substring) => rune.Name.Contains(substring, StringComparison.InvariantCultureIgnoreCase);
public Task<IEnumerable<Rune?>> GetItemsByFamily(RuneFamily family, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.runes.GetItemsWithFilterAndOrdering(
rune => filterByRuneFamily(rune, family),
index, count, orderingPropertyName, descending);
public Task<IEnumerable<Rune?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.runes.GetItemsWithFilterAndOrdering(
rune => filterByName(rune, substring),
index, count, orderingPropertyName, descending);
public Task<int> GetNbItems()
=> parent.runes.GetNbItemsWithFilter(
rune => true);
public Task<int> GetNbItemsByFamily(RuneFamily family)
=> parent.runes.GetNbItemsWithFilter(
rune => filterByRuneFamily(rune, family));
public Task<int> GetNbItemsByName(string substring)
=> parent.runes.GetNbItemsWithFilter(
rune => filterByName(rune, substring));
public Task<Rune?> UpdateItem(Rune? oldItem, Rune? newItem)
=> parent.runes.UpdateItem(oldItem, newItem);
}
}
}

@ -0,0 +1,80 @@
using System;
using Model;
namespace StubLib
{
public partial class StubData
{
private readonly List<Skin> skins = new();
private void InitSkins()
{
skins.Add(new Skin("Stinger", champions[0]));
skins.Add(new Skin("Infernal", champions[0]));
skins.Add(new Skin("All-Star", champions[0]));
skins.Add(new Skin("Justicar", champions[1]));
skins.Add(new Skin("Mecha", champions[1]));
skins.Add(new Skin("Sea Hunter", champions[1]));
skins.Add(new Skin("Dynasty", champions[2]));
skins.Add(new Skin("Midnight", champions[2]));
skins.Add(new Skin("Foxfire", champions[2]));
skins.Add(new Skin("Cyber Pop", champions[3]));
skins.Add(new Skin("Crystal Rose", champions[3]));
skins.Add(new Skin("Elderwood", champions[4]));
skins.Add(new Skin("Snow Day", champions[4]));
skins.Add(new Skin("Bard", champions[4]));
skins.Add(new Skin("Black", champions[5]));
skins.Add(new Skin("Golden", champions[5]));
skins.Add(new Skin("Matador", champions[5]));
}
public class SkinsManager : ISkinsManager
{
private readonly StubData parent;
public SkinsManager(StubData parent)
=> this.parent = parent;
public Task<Skin?> AddItem(Skin? item)
=> parent.skins.AddItem(item);
public Task<bool> DeleteItem(Skin? item)
=> parent.skins.DeleteItem(item);
public Task<IEnumerable<Skin?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.skins.GetItemsWithFilterAndOrdering(
skin => true,
index, count, orderingPropertyName, descending);
private static Func<Skin, Champion?, bool> filterByChampion = (skin, champion) => champion != null && skin.Champion.Equals(champion!);
private static Func<Skin, string, bool> filterByName = (skin, substring) => skin.Name.Contains(substring, StringComparison.InvariantCultureIgnoreCase);
public Task<IEnumerable<Skin?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.skins.GetItemsWithFilterAndOrdering(
skin => filterByChampion(skin, champion),
index, count, orderingPropertyName, descending);
public Task<IEnumerable<Skin?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
=> parent.skins.GetItemsWithFilterAndOrdering(
skin => filterByName(skin, substring),
index, count, orderingPropertyName, descending);
public Task<int> GetNbItems()
=> parent.skins.GetNbItemsWithFilter(
c => true);
public Task<int> GetNbItemsByChampion(Champion? champion)
=> parent.skins.GetNbItemsWithFilter(
skin => filterByChampion(skin, champion));
public Task<int> GetNbItemsByName(string substring)
=> parent.skins.GetNbItemsWithFilter(
skin => filterByName(skin, substring));
public Task<Skin?> UpdateItem(Skin? oldItem, Skin? newItem)
=> parent.skins.UpdateItem(oldItem, newItem);
}
}
}

@ -0,0 +1,35 @@
using Model;
namespace StubLib;
public partial class StubData : IDataManager
{
public StubData()
{
ChampionsMgr = new ChampionsManager(this);
SkinsMgr = new SkinsManager(this);
RunesMgr = new RunesManager(this);
RunePagesMgr = new RunePagesManager(this);
InitSkins();
InitRunePages();
}
public IChampionsManager ChampionsMgr { get; }
public ISkinsManager SkinsMgr { get; }
public IRunesManager RunesMgr { get; }
public IRunePagesManager RunePagesMgr { get; }
private List<Tuple<Champion, RunePage>> championsAndRunePages = new();
private void InitChampionsAndRunePages()
{
championsAndRunePages.Add(Tuple.Create(champions[0], runePages[0]));
}
}

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Model\Model.csproj" />
<ProjectReference Include="..\..\StubLib\StubLib.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup>
</Project>

@ -0,0 +1,338 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Model;
using StubLib;
using static System.Console;
namespace ConsoleTests
{
static class Program
{
static IDataManager dataManager = null!;
static async Task Main(string[] args)
{
try
{
using var servicesProvider = new ServiceCollection()
.AddSingleton<IDataManager, StubData>()
.BuildServiceProvider();
dataManager = servicesProvider.GetRequiredService<IDataManager>();
await DisplayMainMenu();
Console.ReadLine();
}
catch (Exception ex)
{
Debug.WriteLine(ex, "Stopped program because of exception");
throw;
}
}
public static async Task DisplayMainMenu()
{
Dictionary<int, string> choices = new Dictionary<int, string>()
{
[1] = "1- Manage Champions",
[2] = "2- Manage Skins",
[3] = "3- Manage Runes",
[4] = "4- Manage Rune Pages",
[99] = "99- Quit"
};
while(true)
{
int input = DisplayAMenu(choices);
switch(input)
{
case 1:
await DisplayChampionsMenu();
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 99:
WriteLine("Bye bye!");
return;
default:
break;
}
}
}
private static int DisplayAMenu(Dictionary<int, string> choices)
{
int input=-1;
while(true)
{
WriteLine("What is your choice?");
WriteLine("--------------------");
foreach(var choice in choices.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
WriteLine(choice);
}
if(!int.TryParse(ReadLine(), out input) || input == -1)
{
WriteLine("I do not understand what your choice is. Please try again.");
continue;
}
break;
}
WriteLine($"You have chosen: {choices[input]}");
WriteLine();
return input;
}
public static async Task DisplayChampionsMenu()
{
Dictionary<int, string> choices = new Dictionary<int, string>()
{
[0] = "0- Get number of champions",
[1] = "1- Get champions",
[2] = "2- Find champions by name",
[3] = "3- Find champions by characteristic",
[4] = "4- Find champions by class",
[5] = "5- Find champions by skill",
[6] = "6- Add new champion",
[7] = "7- Delete a champion",
[8] = "8- Update a champion",
};
int input = DisplayAMenu(choices);
switch(input)
{
case 0:
int nb = await dataManager.ChampionsMgr.GetNbItems();
WriteLine($"There are {nb} champions");
WriteLine("**********************");
break;
case 1:
{
int index = ReadAnInt("Please enter the page index");
int count = ReadAnInt("Please enter the number of elements to display");
WriteLine($"{count} champions of page {index+1}");
var champions = await dataManager.ChampionsMgr.GetItems(index, count, nameof(Champion.Name));
foreach(var champion in champions)
{
WriteLine($"\t{champion}");
}
WriteLine("**********************");
}
break;
case 2:
{
string substring = ReadAString("Please enter the substring to look for in the name of a champion");
int index = ReadAnInt("Please enter the page index");
int count = ReadAnInt("Please enter the number of elements to display");
var champions = await dataManager.ChampionsMgr.GetItemsByName(substring, index, count, nameof(Champion.Name));
foreach(var champion in champions)
{
WriteLine($"\t{champion}");
}
WriteLine("**********************");
}
break;
case 3:
{
string substring = ReadAString("Please enter the substring to look for in the characteristics of champions");
int index = ReadAnInt("Please enter the page index");
int count = ReadAnInt("Please enter the number of elements to display");
var champions = await dataManager.ChampionsMgr.GetItemsByCharacteristic(substring, index, count, nameof(Champion.Name));
foreach(var champion in champions)
{
WriteLine($"\t{champion}");
}
WriteLine("**********************");
}
break;
case 4:
{
ChampionClass championClass = ReadAnEnum<ChampionClass>($"Please enter the champion class (possible values are: {Enum.GetNames<ChampionClass>().Aggregate("", (name, chaine) => $"{chaine} {name}")}):");
int index = ReadAnInt("Please enter the page index");
int count = ReadAnInt("Please enter the number of elements to display");
var champions = await dataManager.ChampionsMgr.GetItemsByClass(championClass, index, count, nameof(Champion.Name));
foreach(var champion in champions)
{
WriteLine($"\t{champion}");
}
WriteLine("**********************");
}
break;
case 5:
{
string substring = ReadAString("Please enter the substring to look for in the skills of champions");
int index = ReadAnInt("Please enter the page index");
int count = ReadAnInt("Please enter the number of elements to display");
var champions = await dataManager.ChampionsMgr.GetItemsBySkill(substring, index, count, nameof(Champion.Name));
foreach(var champion in champions)
{
WriteLine($"\t{champion}");
}
WriteLine("**********************");
}
break;
case 6:
{
WriteLine("You are going to create a new champion.");
string name = ReadAString("Please enter the champion name:");
ChampionClass championClass = ReadAnEnum<ChampionClass>($"Please enter the champion class (possible values are: {Enum.GetNames<ChampionClass>().Aggregate("", (name, chaine) => $"{chaine} {name}")}):");
string bio = ReadAString("Please enter the champion bio:");
Champion champion = new Champion(name, championClass, bio: bio);
DisplayCreationChampionMenu(champion);
_ = await dataManager.ChampionsMgr.AddItem(champion);
}
break;
case 7:
{
WriteLine("You are going to delete a champion.");
string name = ReadAString("Please enter the champion name:");
var somechampions = await dataManager.ChampionsMgr.GetItemsByName(name, 0, 10, nameof(Champion.Name));
var someChampionNames = somechampions.Select(c => c!.Name);
var someChampionNamesAsOneString = someChampionNames.Aggregate("", (name, chaine) => $"{chaine} {name}");
string champName = ReadAStringAmongPossibleValues($"Who do you want to delete among these champions? (type \"Cancel\" to ... cancel) {someChampionNamesAsOneString}",
someChampionNames.ToArray());
if(champName != "Cancel")
{
await dataManager.ChampionsMgr.DeleteItem(somechampions.Single(c => c!.Name == champName));
}
}
break;
case 8:
{
WriteLine("You are going to update a champion.");
string name = ReadAString("Please enter the champion name:");
var somechampions = await dataManager.ChampionsMgr.GetItemsByName(name, 0, 10, nameof(Champion.Name));
var someChampionNames = somechampions.Select(c => c!.Name);
var someChampionNamesAsOneString = someChampionNames.Aggregate("", (name, chaine) => $"{chaine} {name}");
string champName = ReadAStringAmongPossibleValues($"Who do you want to update among these champions? (type \"Cancel\" to ... cancel) {someChampionNamesAsOneString}",
someChampionNames.ToArray());
if(champName == "Cancel") break;
ChampionClass championClass = ReadAnEnum<ChampionClass>($"Please enter the champion class (possible values are: {Enum.GetNames<ChampionClass>().Aggregate("", (name, chaine) => $"{chaine} {name}")}):");
string bio = ReadAString("Please enter the champion bio:");
Champion champion = new Champion(champName, championClass, bio: bio);
DisplayCreationChampionMenu(champion);
await dataManager.ChampionsMgr.UpdateItem(somechampions.Single(c => c!.Name == champName), champion);
}
break;
default:
break;
}
}
public static void DisplayCreationChampionMenu(Champion champion)
{
Dictionary<int, string> choices = new Dictionary<int, string>()
{
[1] = "1- Add a skill",
[2] = "2- Add a skin",
[3] = "3- Add a characteristic",
[99] = "99- Finish"
};
while(true)
{
int input = DisplayAMenu(choices);
switch(input)
{
case 1:
string skillName = ReadAString("Please enter the skill name:");
SkillType skillType = ReadAnEnum<SkillType>($"Please enter the skill type (possible values are: {Enum.GetNames<SkillType>().Aggregate("", (name, chaine) => $"{chaine} {name}")}):");
string skillDescription = ReadAString("Please enter the skill description:");
Skill skill = new Skill(skillName, skillType, skillDescription);
champion.AddSkill(skill);
break;
case 2:
string skinName = ReadAString("Please enter the skin name:");
string skinDescription = ReadAString("Please enter the skin description:");
float skinPrice = ReadAFloat("Please enter the price of this skin:");
Skin skin = new Skin(skinName, champion, skinPrice, description: skinDescription);
break;
case 3:
string characteristic = ReadAString("Please enter the characteristic:");
int value = ReadAnInt("Please enter the value associated to this characteristic:");
champion.AddCharacteristics(Tuple.Create(characteristic, value));
break;
case 99:
return;
default:
break;
}
}
}
private static int ReadAnInt(string message)
{
while(true)
{
WriteLine(message);
if(!int.TryParse(ReadLine(), out int result))
{
continue;
}
return result;
}
}
private static float ReadAFloat(string message)
{
while(true)
{
WriteLine(message);
if(!float.TryParse(ReadLine(), out float result))
{
continue;
}
return result;
}
}
private static string ReadAString(string message)
{
while(true)
{
WriteLine(message);
string? line = ReadLine();
if(line == null)
{
continue;
}
return line!;
}
}
private static TEnum ReadAnEnum<TEnum>(string message) where TEnum :struct
{
while(true)
{
WriteLine(message);
if(!Enum.TryParse<TEnum>(ReadLine(), out TEnum result))
{
continue;
}
return result;
}
}
private static string ReadAStringAmongPossibleValues(string message, params string[] possibleValues)
{
while(true)
{
WriteLine(message);
string? result = ReadLine();
if(result == null) continue;
if(result != "Cancel" && !possibleValues.Contains(result!)) continue;
return result!;
}
}
}
}
Loading…
Cancel
Save