Compare commits

...

84 Commits

Author SHA1 Message Date
Corentin RICHARD f211a89651 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 47b35b48e3 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 3f58547a01 fix error
2 years ago
Pierre FERREIRA fe13bf5d7d Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 8489b0b848 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R f46b2d9aec quality review
2 years ago
Pierre FERREIRA b0166276bf Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin RICHARD f4dd0dd152 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R b2b59223ec suppression Maui
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 8059cf28f3 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP
2 years ago
Corentin R f82c425e30 modification README
2 years ago
Pierre Ferreira 28e5a0e570 correction du count, desormais fonctionnel en ligne de commande
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira d38600ce4b test maui
2 years ago
Pierre FERREIRA 3e605c9fec Merge pull request 'DevPF' (#38) from DevPF into master
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira 446d2d84a2 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into DevPF
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 3aba9a431a Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA 71cee62cad Merge pull request 'RuneBranch' (#36) from RuneBranch into master
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R fee25f5dff adding client console
2 years ago
Corentin R 5280f569ea merge
2 years ago
Corentin R b94825d358 Ajout d'un client utilisant http
2 years ago
Pierre Ferreira 116d150949 Merge branch 'master' into RuneBranch
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira f3274ca258 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into DevPF
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin RICHARD 45d4366003 Merge pull request 'Creation du client console' (#35) from ConsoleClient into master
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA 31bfa2b056 Ajout Coordonnée
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin RICHARD b99148bc73 Merge pull request 'advancedController' (#34) from advancedController into master
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 848075afc1 db changes
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA 03507e9c8a Maj état des livrables EF
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA 9d2d8c3805 logs ✔️
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA c2a4916dc7 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 38af6e216c Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into advancedController
2 years ago
Corentin R 5d7002c8e8 add all logs
2 years ago
Pierre FERREIRA 11e6674783 📝 rédaction du barème de l'Entity Framework
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA feaa59f594 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R bc5186fa9d ajout logErrors
2 years ago
Corentin R ae3c163e45 Ajout de log
2 years ago
Corentin R 32b0ee4012 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into advancedController
2 years ago
Pierre Ferreira 6afc9ed906 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira f04c434c71 📝 Début de la formalisation du readme !
2 years ago
Pierre Ferreira 41de783e44 ajout d'un RuneController (et donc de RuneMapper et RuneDTO) 📦
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R edc7d4eaa2 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into advancedController
2 years ago
Corentin R 6c48f7ec08 commit adding test
2 years ago
Pierre Ferreira 3da8ab952a Ajout des liaisons One to many pour champion et skill, et pour runepage et rune, migration fonctionnel avec comme context le loldbcontext, mais pas avec le stubbed
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA e5e3b4acd4 Merge pull request 'RuneBranch' (#32) from RuneBranch into master
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira a246358bbf merge avec master 📦
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre FERREIRA 7a7718bc6b Merge pull request 'httpClient' (#30) from httpClient into master
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira 9ff4f2cd4d Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into httpClient
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin RICHARD 02b1d91d0a Merge pull request 'advancedController' (#29) from advancedController into master
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 1aca79ec28 fix ef Test
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 70c7696a6c Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into advancedController
2 years ago
Corentin R 8a58b97d0b Post fix no more 🐛
2 years ago
Corentin RICHARD 5554d01761 Merge pull request 'advancedController' (#28) from advancedController into master
continuous-integration/drone/push Build is failing Details
2 years ago
Corentin R 3b2cfba59b ajout count
continuous-integration/drone/push Build is failing Details
2 years ago
Corentin R f6a3075218 Ajout put et delete
2 years ago
Corentin R 9e00ef300d Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into advancedController
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R d03df90884 Ajout put & delete
2 years ago
Pierre Ferreira 14ddb60602 ManyMany Champions -> RUnePage Working !
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R b714c4c0f1 added put and delete
2 years ago
Corentin RICHARD d5a08b7664 Merge pull request 'EFDataManager' (#27) from EFDataManager into master
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R e6e16bd6af Liaison de l'API avec l'EF
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira bd8de0eee8 ajout de l'httpClientManager pour la liaison Client-API et codage des fonctions principale de l'httpclient (pas encore testées) 📦
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R b41894300d Problem not fix
2 years ago
Pierre Ferreira 39eb15aeea bug fix 🐛
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira 936922f772 Mise a jour avec master et ajout d'info dans le StubbedContext
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira e1e3f8b6d1 Merge branch 'master' of into SkillBranch
2 years ago
Pierre Ferreira 556260df84 Debut Many to Many entre Champion et Runes 📦
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira 3a53d55ff4 Création des classes Rune, RunePage, famille et Catégory
continuous-integration/drone/push Build is failing Details
2 years ago
Corentin R 503c69e553 fix 🐛
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R c06dbf0c0e merge
continuous-integration/drone/push Build is failing Details
2 years ago
Corentin R 7a9b9370e2 add
2 years ago
Corentin R 6f6fc4c5e0 Implement add
2 years ago
Pierre FERREIRA 31113c6ee7 Merge pull request 'SkinBranch' (#23) from SkinBranch into master
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira f01df10138 finition du OneToMany des Skills ! 🎉
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira 5423d0f282 tentative de resolution du probleme de migration (coco a toi) 🐛
continuous-integration/drone/push Build is passing Details
2 years ago
Pierre Ferreira baf7343420 merge
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira 5bf297f7b1 push de migration marchant sans le second hasdata, push pour merge
2 years ago
Corentin R a2d5abd371 Merge branch 'master' of https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP into advancedController
continuous-integration/drone/push Build is passing Details
2 years ago
Corentin R 2b4726f18b fix tests
2 years ago
Corentin R 2c0d3f8432 Adding all param to Skins and image to champion
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira 10d4be1b54 continuation de la recherche du probleme : seed, apparament lié a des conflits de OneToMany
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira 11137d89aa 📦 Création du OneToMany mais probleme dans la création de la migration
2 years ago
Pierre Ferreira c72adccc1a tentative de reglage du probleme des tests suite a l'ajout des skin, voir pour le One to Many ??
2 years ago
Pierre Ferreira e3a9577eaa Ajout de la class Skin et création de la branche
continuous-integration/drone/push Build is failing Details
2 years ago
Pierre Ferreira 93a1c42ad2 🧪 ajout du premier test et des charactéristiques(pb sur cette dernière nonobstant..) 🩹
2 years ago
Pierre Ferreira 9536d38745 🚀 création d'une branche perso pour eviter les conflits, et mise sur le depots du code : la creation de champion en base de donnée avec nom, bio et icone
2 years ago

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33213.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EF_LoL", "EF_LoL\EF_LoL.csproj", "{1AF6FE09-1ABF-4C51-8EC6-D2938876AAD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "TestProject\TestProject.csproj", "{1A0B75E2-ECCE-47F3-A8FB-79F48F76E9A1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1AF6FE09-1ABF-4C51-8EC6-D2938876AAD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AF6FE09-1ABF-4C51-8EC6-D2938876AAD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AF6FE09-1ABF-4C51-8EC6-D2938876AAD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AF6FE09-1ABF-4C51-8EC6-D2938876AAD2}.Release|Any CPU.Build.0 = Release|Any CPU
{1A0B75E2-ECCE-47F3-A8FB-79F48F76E9A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A0B75E2-ECCE-47F3-A8FB-79F48F76E9A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A0B75E2-ECCE-47F3-A8FB-79F48F76E9A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A0B75E2-ECCE-47F3-A8FB-79F48F76E9A1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1EA5AF67-3A7C-4B6B-BE39-837D683F5AB3}
EndGlobalSection
EndGlobal

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF_LoL
{
public class ChampionDBContext : DbContext
{
public ChampionDBContext()
{ }
public ChampionDBContext(DbContextOptions<ChampionDBContext> options)
: base(options)
{ }
//ChampionEntity champ1 = new ChampionEntity("Bob");
//ChampionEntity champ2 = new ChampionEntity("Fanta");
public DbSet<ChampionEntity> ChampionEntity { get; set; }
//protected override void OnConfiguring(DbContextOptionsBuilder options)
// => options.UseSqlite("Data Source= EF_LoL.MyDataBase.db");
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
if (!options.IsConfigured)
{
options.UseSqlite("Data Source= EF_LoL.MyDataBase.db");
}
}
}
}

@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
namespace EF_LoL
{
public class ChampionEntity
{
//dotnet ef database update --context ChampionDBContext --project EF_LoL
[Key]
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 string Icon { get; set; }
public ChampionEntity(string name, string icon = "", string bio = "")
{
Name = name;
Icon = icon;
Bio = bio;
///Characteristics = new ReadOnlyDictionary<string, int>(characteristics);
}
///public ReadOnlyDictionary<string, int> Characteristics { get; private set; }
///private readonly Dictionary<string, int> characteristics = new Dictionary<string, int>();
// creer table avec db context et db set de champion
// puis ajout d'un nouveau champion
// pour ajouté un attribut : supprimer nos migrations et nos db
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 ChampionEntity);
}
public override int GetHashCode()
=> Name.GetHashCode() % 997;
public bool Equals(ChampionEntity? other)
=> Name.Equals(other?.Name);
public override string ToString()
{
StringBuilder sb = new StringBuilder($"{Name}");
if (!string.IsNullOrWhiteSpace(bio))
{
sb.AppendLine($"\t{bio}");
}
return sb.ToString();
}
///// Characteristique
////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;
//// }
////}
}
}

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

@ -0,0 +1,42 @@
// <auto-generated />
using EF_LoL;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace EFLoL.Migrations
{
[DbContext(typeof(ChampionDBContext))]
[Migration("20230204093038_MyMigration")]
partial class MyMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
modelBuilder.Entity("EF_LoL.ChampionEntity", b =>
{
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Bio")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Name");
b.ToTable("ChampionEntity");
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,34 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace EFLoL.Migrations
{
/// <inheritdoc />
public partial class MyMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ChampionEntity",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
Bio = table.Column<string>(type: "TEXT", nullable: false),
Icon = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChampionEntity", x => x.Name);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ChampionEntity");
}
}
}

@ -0,0 +1,39 @@
// <auto-generated />
using EF_LoL;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace EFLoL.Migrations
{
[DbContext(typeof(ChampionDBContext))]
partial class ChampionDBContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
modelBuilder.Entity("EF_LoL.ChampionEntity", b =>
{
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Bio")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Name");
b.ToTable("ChampionEntity");
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,28 @@
// See https://aka.ms/new-console-template for more information
using EF_LoL;
Console.WriteLine("Hello, World!");
ChampionEntity chewie = new ChampionEntity("Chewbacca");
ChampionEntity yoda = new ChampionEntity ("Yoda");
ChampionEntity ewok = new ChampionEntity ("Ewok");
using (var context = new ChampionDBContext())
{
// Crée des Champion et les insère dans la base
Console.WriteLine("Creates and inserts new Champion");
context.ChampionEntity.Add(chewie);
context.ChampionEntity.Add(yoda);
context.ChampionEntity.Add(ewok);
context.SaveChanges();
}
using (var context = new ChampionDBContext())
{
foreach (var n in context.ChampionEntity)
{
Console.WriteLine($"{n.Name} - {n.Bio} [ {n.Icon} ]");
}
context.SaveChanges();
}

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EF_LoL\EF_LoL.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,45 @@
using EF_LoL;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using Xunit;
namespace TestProject
{
public class UnitTest1
{
[Fact]
public void Test1()
{
var options = new DbContextOptionsBuilder<ChampionDBContext>()
.UseInMemoryDatabase(databaseName: "Add_Test_database")
.Options;
//prepares the database with one instance of the context
using (var context = new ChampionDBContext(options))
{
ChampionEntity chewie = new ChampionEntity("Chewbacca");
ChampionEntity yoda = new ChampionEntity("Yoda");
ChampionEntity ewok = new ChampionEntity("Ewok");
Console.WriteLine("Creates and inserts new Champion for tests");
context.ChampionEntity.Add(chewie);
context.ChampionEntity.Add(yoda);
context.ChampionEntity.Add(ewok);
context.SaveChanges();
}
//prepares the database with one instance of the context
using (var context = new ChampionDBContext(options))
{
Assert.Equal(3, context.ChampionEntity.Count());
Assert.Equal("Chewbacca", context.ChampionEntity.First().Name);
}
}
}
}

@ -0,0 +1 @@
global using Xunit;

@ -1,4 +1,156 @@
# prepaLoL
# Projet d'Entity FrameWork et Consomation et Développement de services
Notre projet à pour objectif la liaison entre une base de donnée et un client, par l'utilisation d' ``EntityFramework`` et d'une ``API`` C#.
![C#](https://img.shields.io/badge/c%23-%23239120.svg?style=for-the-badge&logo=c-sharp&logoColor=white)
![JWT](https://img.shields.io/badge/JWT-black?style=for-the-badge&logo=JSON%20web%20tokens)
![Markdown](https://img.shields.io/badge/markdown-%23000000.svg?style=for-the-badge&logo=markdown&logoColor=white)
> *A noter que seul la v1 est prise en compte, la v2 et v2.2 ne sont presentes uniquement pour prouver notre capacité à versionner*
### Ce projet est decoupé en deux parties :
# :alien: Consomation et Développement de services
### :checkered_flag: État des livrables :
> * :heavy_check_mark: Mise en place de toutes les opérations CRUD
> * :heavy_check_mark: API RESTful (respect des règles de routage, utilisation des bons status code ...)
> * :heavy_check_mark: Utilisation des fichiers configurations
> * :heavy_check_mark: Versionnage de l'api (avec versionnage de la doc)
> * :heavy_check_mark: Logs
> * :heavy_check_mark: Tests unitaires
> * :heavy_exclamation_mark: Réalisation du client MAUI et liaison avec l'api
> * :heavy_check_mark:Liaison avec la base de données
> * :heavy_check_mark:Filtrage + Pagination des données
> * :heavy_check_mark: Propreté du code (Vous pouvez vous servir de sonarqube)
> * :heavy_check_mark: Dockerisation et Hébergement des API (CodeFirst)
> * :heavy_exclamation_mark: Sécurité
> * :heavy_check_mark: Utilisation SonarQube
[![Build Status](https://codefirst.iut.uca.fr/api/badges/corentin.richard/EntityFramework_ConsoDeServices_TP/status.svg)](https://codefirst.iut.uca.fr/corentin.richard/EntityFramework_ConsoDeServices_TP)
---
# :package: Entity FrameWork
### :checkered_flag: État des livrables :
Partie 1 :
* Exo1 : :heavy_check_mark:
une base de données
une table de champion
utilisation du client console/mobile
requetes CRUD (+ tri, filtrage)
* Exo2 : :heavy_check_mark:
UT
Base de données stubbée
SQLiteInMemory
* Exo3 : :heavy_check_mark:
Déploiement EF et tests via code#0
---
Partie 2 :
* Exo4 : :heavy_check_mark:
implémentation des runes et skins (1 table -> pas de relation)
* Exo5 : :heavy_check_mark:
Relation entre champion et skin (OneToMany)
* Exo6 : :heavy_check_mark:
Relation entre Champion, RunePage et Rune (ManyToMany)
> La relation entre Rune et RunePage à été simplifiée par manque de temps, il ne s'agit donc pas d'un dictionaire mais d'un OneToMany.
* Exo7 : :heavy_check_mark:
mapping entre model et entité (intégration de qualité)
(en 1 table et avec relations)
* Exo8 : :heavy_exclamation_mark:
Ajouter le paterne UnitOfWork (rollback en cas de probleme sur les transaction)
---
### Diagramme d'architechture :
![](./docAsset/Diagramme%20d'architecture.jpg)
Le schéma ci-dessus décris l'architecture finale que doit avoir le projet,
# Implémentation attendue :
Tout en haut du schéma, la partie client est composé du client MAUI et et du client Console, ceux-ci permettent l'affichage des ressources, l'utilisation de l'architecture et donc de tester si tout le projet fonctionne. Celui-ci utilise le HTTPDataManager qui lui permet d'effectuer les requêtes à l'API afin de récupérer les données. Il hérite de IDataManager et peux donc être remplacé par EFDataManager, court-circuitant ainsi l'API ou par StubLib, n'utilisant pas l'API et l'EF. Le DataManager utilise l'une des extensions mapper pour convertir les objets DTO en Model.
> On indique aux client d'utiliser le HttpDataManager :
builder.Services.AddScoped<IDataManager,HTTPDataManager>();
En second, la partie API, celle-ci s'occupe de recevoir les requêtes et de renvoyer les objet en conséquent. Dans l'implémentation idéale, l'API utilise l'EFDataManger pour faire appel aux données stockés en base de données. Il hérite lui aussi de IDataManager mais ne peut être remplacé que par le StubLib.Il utilise lui aussi des extensions mapper pour convertir les objets Entity en Model.
> On indique à l'API d'utiliser le EFDataManager :
builder.Services.AddScoped<IDataManager,EFDataManager>();
Enfin, le dernier service implémenté est EntityFramework, l'ORM utilisé pour communiquer avec la base de données, celle-ci elle-même basé sur les données du StubLib grâce à la méthode HasData dans notre DbContext, il récupère et enregistre les objets Entity grâce aux DBSet d'objets. La fluent API permet de définir précisement les attributs de la base de données
# Implémentation Réelle
Actuellement, l'entiereté du projet est relié ensemble, cependant les fonctionnalités n'ont été implémentés que partielement, suite à un manque de temps nous avons préféré effectuer le squelette du projet et de relier l'ensemble plutôt que de rajouter des méthodes qui ne seraient pas utilisées.
## 1 - **Clients**
Premièrement, les clients, ils dépendent de l'implémentation de HTTPDataManager :
Le client MAUI : Suite à des difficultées de compatibilité et par manque de temps nous n'avons pas pu l'implémenter après plusieurs essais, le client console le remplace donc.
Le client console est fonctionnel mais ne peut effectuer que peu de méthodes dans sont menu textuel :
- Compter les champions
- Afficher les champions
## 2 - **API**
L'**HTTPDataManger** permet d'appeler les méthodes basiques de la partie Champion de l'API.
L'**API** ne présente qu'un seul controlleur, celui de champion. Nous avons préféré faire un seul complet plutôt que plusieurs incomplets. Celui-ci a l'utilisation des **logs**, des **codes de retours** et respecte les **règles Rest**, celui-ci implémentant les méthodes **CRUD**. Une seconde **version** est disponible pour implémenter un versionning.
La méthode GET permet le **filtrage et la pagination** des données, ces méthodes sont **testées unitairement** et l'API est **déployé** avec le projet en conteneur.
## 3 - **EntityFramework**
L'**EFDataManger** permet d'effectuer les méthodes CRUD sur EntityFramework.
L'**EntityFramework** a été implémenté avec toutes les classes **Entity** dérivant du modèle, en utilisant **OneToMany** et **ManyToMany** de facon dérivé de celle prévue. Elle est utilsé sur **base** du stub et est **testé** unitairement grâce à **SQLiteInMemory**. Ces méthodes **CRUD** sont implémentées grâce à l'utilisation de l'**EFDataManager**, le *Mapper* entre entity et model est alors requis. Enfin il est **deployé**, cependant nous n'avons pas eu le temps d'aborder le pattern ***UnitOfWork***.
# :rocket: Comment lancer le projet
## 1 - Cloner le dépot
Premièrement il faut cloner le depot git à l'addresse suivant :
git clone https://codefirst.iut.uca.fr/git/corentin.richard/EntityFramework_ConsoDeServices_TP.git
## 2 - Ouvir le projet avec VisualStudio
clique droit sur le dossier cloné > ouvrir avec Visual Studio
## 3 - Configurer le démarrage du projet
> clique droit sur le projet dans l'explorateur de solution > Configure Startup Projects ... > Multpile Startup Project
Et mettez l'action Start à LoLAPI et à ConsoleApplication(c#) ou LoLApp(MAUI)
## 4 - Lancement du projet
Vous pouvez alors lancer le projet grâce à la flèche verte, bonne navigation !
# Développeurs :
``Corentin Richard`` : **[corentin.richard@etu.uca.fr](https://codefirst.iut.uca.fr/git/corentin.richard)**
``Pierre Ferreira`` : **[pierre.ferreira@etu.uca.fr](https://codefirst.iut.uca.fr/git/pierre.ferreira)**
# Diagrammes du Model Initial
## Diagramme de classes du modèle
```mermaid

@ -0,0 +1,4 @@
[*.cs]
# CS8604: Possible null reference argument.
dotnet_diagnostic.CS8604.severity = none

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@ -11,12 +11,14 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\EntityFramework\EntityFramework.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>

@ -8,6 +8,8 @@ using System.Drawing;
using System;
using API_LoL.Mapper;
using System.Xml.Linq;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.Reflection.PortableExecutable;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
@ -21,20 +23,33 @@ namespace API_LoL.Controllers
{
public ChampionsController(IDataManager Manager) {
this._logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<ChampionsController>();
this.ChampionsManager = Manager.ChampionsMgr;
this.SkinsManager = Manager.SkinsMgr;
}
private IChampionsManager ChampionsManager;
private ISkinsManager SkinsManager;
//private StubData stubData;
private ILogger logger;
private readonly ILogger _logger;
// GET api/<ChampionController>/5
[HttpGet("count")]
public async Task<IActionResult> GetCount()
{
_logger.LogInformation(message: "count returned", "Get", "/Champion/Count", 200, DateTime.Now);
return Ok(ChampionsManager.GetNbItems());
}
[HttpGet]
public async Task<IActionResult> Get(string? name = null,String? skill = null, String? characteristic = null,int index = 0,int size =10)
{
if (size - index > 10)
{
_logger.LogError(message : "Oversized","Get","/Champion",400,"name : "+name,"skill : "+skill,"characteristics : "+characteristic,"index : "+index,"size : "+size,DateTime.Now);
return BadRequest();
}
if (!string.IsNullOrEmpty(name))
@ -42,91 +57,188 @@ namespace API_LoL.Controllers
var list = await ChampionsManager.GetItemsByName(name, index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned by name", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Champion found by name", "Get", "/Champion", 204, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return NoContent(); }
}
else if(!string.IsNullOrEmpty(skill)) {
var list = await ChampionsManager.GetItemsBySkill(skill, index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned by skill", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Champion found by skill", "Get", "/Champion", 204, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return NoContent(); }
}
else if(!string.IsNullOrEmpty (characteristic)) {
var list = await ChampionsManager.GetItems(index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned by characteristic", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Champion found by char", "Get", "/Champion", 204, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return NoContent(); }
}
else {
var list = await ChampionsManager.GetItems(index, size);
if (list.Count() != 0)
{
_logger.LogInformation(message: "Champion returned default", "Get", "/Champion", 200, "name : " + name, "skill : " + skill, "characteristic : " + characteristic, "index : " + index, "size : " + size, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()));
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Champion found Default", "Get", "/Champion", 204, "name : " + name,"skill : " + skill,"characteristic : "+ characteristic,"index : "+index,"size : "+size, DateTime.Now);
return NoContent();
}
}
}
[HttpGet("name")]
public async Task<IActionResult> GetByName(String name)
{
if (string.IsNullOrEmpty(name)) return BadRequest();
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "No paramater given", "Get", "/Champion/Name", 400, "name : " + name, DateTime.Now);
return BadRequest();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
_logger.LogInformation(message: "Champion found", "Get", "/Champion/Name", 20, "name : " + name, DateTime.Now);
return Ok(list.Select(champion => champion?.ToDTO()).First());
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Champion found", "Get", "/Champion/Name", 204, "name : " + name, DateTime.Now);
return NoContent();
}
}
[HttpGet("name/skins")]
public async Task<IActionResult> GetSkinsByName(String name)
{
if (string.IsNullOrEmpty(name)) return BadRequest();
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "No paramater given", "Get", "/Champion/Name/Skins", 400, "name : " + name, DateTime.Now);
return BadRequest();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
var skins = await SkinsManager.GetItemsByChampion(list.First(), 0, await SkinsManager.GetNbItemsByChampion(list.First()));
if (skins.Count() != 0)
var nb = await SkinsManager.GetNbItemsByChampion(list.First());
if (nb != 0)
{
var skins = await SkinsManager.GetItemsByChampion(list.First(), 0, nb);
return Ok(skins.Select(skin => skin?.ToDTO()));
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Skin found found", "Get", "/Champion/Name/Skins", 204, "name : " + name, DateTime.Now);
return NoContent(); }
}
else { return NoContent(); }
else {
_logger.LogInformation(message: "No Champion found", "Get", "/Champion/Name/Skins", 204, "name : " + name, DateTime.Now);
return NoContent();
}
}
// POST api/<ChampionController>
[HttpPost]
//[HttpGet("name/skills")]
//public async Task<IActionResult> GetSkillsByName(String name)
//{
// if (string.IsNullOrEmpty(name)) return BadRequest();
// var list = await ChampionsManager.GetItemsByName(name, 0, 1);
// if (list.Count() == 1)
// {
// var skins = await SkinsManager.GetItemsByChampion(list.First(), 0, await SkinsManager.GetNbItemsByChampion(list.First()));
// if (skins.Count() != 0)
// {
// return Ok(skins.Select(skin => skin?.ToDTO()));
// }
// else { return NoContent(); }
// }
// else { return NoContent(); }
//}
// POST api/<ChampionController>
[HttpPost]
public async Task<IActionResult> Post(ChampionDTO champion)
{
if (champion == null)
{
_logger.LogError(message: "Null paramater given", "Post", "/Champion", 422, "champion : " + champion.toString, DateTime.Now);
return UnprocessableEntity();
}
else
{
var list = await ChampionsManager.GetItemsByName(champion.Name, 0, 1);
Champion champ = list.FirstOrDefault();
if (champ != null)
{
if(champ.Name == champion.Name)
{
_logger.LogError(message: "Champion with this id already exists", "Post", "/Champion", 409, "champion : " + champion.toString, DateTime.Now);
return Conflict(champion);
}
}
await ChampionsManager.AddItem(champion.ToChampion());
_logger.LogInformation(message: "Champion created", "Post", "Champion/Name", 201, "champion : " + champion.toString, DateTime.Now);
return CreatedAtAction("Post",champion);
}
}
// PUT api/<ChampionController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
[HttpPut("name")]
public async Task<IActionResult> Put(string name, ChampionDTO championDTO)
{
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "Null paramater given for Name", "Put", "/Champion/Name", 400,"name : "+name, "champion : " + championDTO.toString, DateTime.Now);
return BadRequest();
}
if(championDTO == null)
{
_logger.LogError(message: "Null paramater given for Champion", "Put", "/Champion/Name", 422, "name : " + name, "champion : " + championDTO.toString, DateTime.Now);
return UnprocessableEntity();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
_logger.LogInformation(message: "Champion updated", "Put", "Champion/Name", 200, "name : " + name, "champion : " + championDTO.toString, DateTime.Now);
return Ok(ChampionsManager.UpdateItem(list.First(), championDTO.ToChampion()));
}
else {
_logger.LogInformation(message: "No champion Found", "Put", "/Champion/Name", 204, "name : " + name, "champion : " + championDTO.toString, DateTime.Now);
return NoContent();
}
}
// DELETE api/<ChampionController>/5
[HttpDelete("{id}")]
public void Delete(int id)
[HttpDelete("name")]
public async Task<IActionResult> Delete(string name)
{
if (string.IsNullOrEmpty(name))
{
_logger.LogError(message: "Null paramater given for Name", "Delete", "/Champion/Name", 400, "name : " + name, DateTime.Now);
return BadRequest();
}
var list = await ChampionsManager.GetItemsByName(name, 0, 1);
if(list.Count() == 1){
_logger.LogInformation(message: "Champion Deleted", "Delete", "/Champion/Name", 200, "name : " + name, DateTime.Now);
return Ok(await ChampionsManager.DeleteItem(list.First()));
}else {
_logger.LogInformation(message: "No champion Found", "Delete", "/Champion/Name", 204, "name : " + name, DateTime.Now);
return NoContent(); }
}
}
}

@ -0,0 +1,124 @@
using API_LoL.Mapper;
using DTO;
using EntityFramework;
using Microsoft.AspNetCore.Mvc;
using Model;
namespace API_LoL.Controllers
{
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class RunesController : ControllerBase
{
public RunesController(IDataManager Manager)
{
this.RunesManager = Manager.RunesMgr;
}
private IRunesManager RunesManager;
// GET api/<ChampionController>/5
[HttpGet("count")]
public async Task<IActionResult> GetCount()
{
return Ok(RunesManager.GetNbItems());
}
[HttpGet]
public async Task<IActionResult> Get(string? name = null, string desc = null, EnumRuneFamily Family = EnumRuneFamily.Unknown, LargeImage Image = null, int index = 0, int size = 10)
{
if (size - index > 10)
{
return BadRequest();
}
if (!string.IsNullOrEmpty(name))
{
var list = await RunesManager.GetItemsByName(name, index, size);
if (list.Count() != 0)
{
return Ok(list.Select(rune => rune?.ToDTO()));
}
else { return NoContent(); }
}
else
{
var list = await RunesManager.GetItems(index, size);
if (list.Count() != 0)
{
return Ok(list.Select(champion => champion?.ToDTO()));
}
else { return NoContent(); }
}
}
[HttpGet("name")]
public async Task<IActionResult> GetByName(String name)
{
if (string.IsNullOrEmpty(name)) return BadRequest();
var list = await RunesManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
return Ok(list.Select(rune => rune?.ToDTO()).First());
}
else { return NoContent(); }
}
// POST api/<ChampionController>
[HttpPost]
public async Task<IActionResult> Post(RuneDTO rune)
{
if (rune == null)
{
return UnprocessableEntity();
}
else
{
var champ = await RunesManager.GetItemsByName(rune.Name, 0, 1);
if(champ.Count() > 0)
if (champ.Where(c => c.Name == rune.Name).Count() == 1)
{
return Conflict(rune);
}
await RunesManager.AddItem(rune.ToRune());
return CreatedAtAction("Post", rune);
}
}
// PUT api/<ChampionController>/5
[HttpPut("name")]
public async Task<IActionResult> Put(string name, RuneDTO rune)
{
if (string.IsNullOrEmpty(name))
return BadRequest();
if (rune == null)
return UnprocessableEntity();
var list = await RunesManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
return Ok(RunesManager.UpdateItem(list.First(), rune.ToRune()));
}
else { return NoContent(); }
}
// DELETE api/<ChampionController>/5
[HttpDelete("name")]
public async Task<IActionResult> Delete(string name)
{
if (string.IsNullOrEmpty(name))
return BadRequest();
var list = await RunesManager.GetItemsByName(name, 0, 1);
if (list.Count() == 1)
{
return Ok(await RunesManager.DeleteItem(list.First()));
}
else { return NoContent(); }
}
}
}

@ -12,19 +12,13 @@ namespace DTO.Mapper
{
public static ChampionDTO ToDTO(this Champion champion)
{
return new ChampionDTO(champion.Name, champion.Bio, champion.Icon,champion.Class.ToDTO().ToString());
//return new ChampionDTO(champion.Name, champion.Bio, champion.Icon, champion.Skills);
return new ChampionDTO(champion.Name, champion.Bio, champion.Icon, champion.Class.ToDTO(), champion.Image.Base64);
}
public static Champion ToChampion(this ChampionDTO champion)
{
Champion champ = new Champion(champion.Name, champion.Class.ToChampionClass(), champion.Icon, "", champion.Bio);
return new Champion(champion.Name, champClass: champion.Class.ToChampionClass(),icon: champion.Icon,bio: champion.Bio,image :champion.Image);
//foreach (Skill skill in champion.Skills)
//{
// champ.AddSkill(skill);
//}
return champ;
}
}
}

@ -0,0 +1,19 @@
using DTO;
using Model;
namespace API_LoL.Mapper
{
public static class RuneMapper
{
public static RuneDTO ToDTO(this Rune rune)
{
return new RuneDTO(rune.Name, rune.Description, rune.Family, rune.Image, rune.Icon);
}
public static Rune ToRune(this RuneDTO rune)
{
return new Rune(rune.Name, rune.Family, rune.Icon, rune.Image.Base64, rune.Description);
}
}
}

@ -7,12 +7,12 @@ namespace API_LoL.Mapper
{
public static SkinDTO ToDTO(this Skin skin)
{
return new SkinDTO(skin.Name, skin.Description, skin.Icon);
return new SkinDTO(skin.Name, skin.Description, skin.Icon,skin.Image.Base64,skin.Price);
}
public static Skin ToSkin(this SkinDTO skin)
{
return new Skin(skin.Name, null, icon:skin.Icon) ;
return new Skin(skin.Name, null,price: skin.Price, icon:skin.Icon,image: skin.Image,description: skin.Description) ;
}
}
}

@ -1,6 +1,9 @@
using API_LoL;
using EntityFramework;
using EntityFramework.Manager;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.Extensions.Logging;
using Model;
using StubLib;
@ -11,7 +14,7 @@ var builder = WebApplication.CreateBuilder(args);
///NOT WORKING WHEN CHANGING VERSIONS :
/// voir sur https://blog.christian-schou.dk/how-to-use-api-versioning-in-net-core-web-api/ rubrique "Configure SwaggerOptions"
/// (mais requiere l'injection de dépendance).
/// (mais requiere l'injection de d<EFBFBD>pendance).
/// Sinon, code plus simple disponible par le prof
@ -37,13 +40,24 @@ builder.Services.AddControllers();
builder.Services.AddScoped<IDataManager,StubData>();
//builder.Services.AddScoped<IDataManager,StubData>();
builder.Services.AddHttpClient();
//builder.Services.AddScoped<IDataManager,StubData>();
builder.Services.AddScoped<IDataManager,EFDataManager>();
builder.Services.AddDbContext<LoLDBContextWithStub>();
var app = builder.Build();
using(var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetService<LoLDBContextWithStub>();
context.Database.EnsureCreated();
}
var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();

Binary file not shown.

@ -3,6 +3,7 @@ using DTO;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using Model;
using StubLib;
using System.Collections;
@ -21,7 +22,7 @@ namespace Api_UT
public async Task Get_Default_OkList()
{
List<ChampionDTO> list = new List<ChampionDTO> {new ChampionDTO("Akali","","","Assassin"), new ChampionDTO("Aatrox", "", "", "Fighter"), new ChampionDTO("Ahri", "", "", "Mage"), new ChampionDTO("Akshan", "", "", "Marksman"), new ChampionDTO("Bard", "", "","Support"), new ChampionDTO("Alistar", "", "","Tank") };
List<ChampionDTO> list = new List<ChampionDTO> {new ChampionDTO("Akali","","","Assassin",""), new ChampionDTO("Aatrox", "", "", "Fighter",""), new ChampionDTO("Ahri", "", "", "Mage",""), new ChampionDTO("Akshan", "", "", "Marksman",""), new ChampionDTO("Bard", "", "","Support",""), new ChampionDTO("Alistar", "", "","Tank","") };
IActionResult a = await api.Get();
a.Should().NotBeNull();
var aObject = a as OkObjectResult;
@ -42,7 +43,7 @@ namespace Api_UT
[TestMethod]
public async Task Get_2First_OkListOf2()
{
List<ChampionDTO> list = new List<ChampionDTO> { new ChampionDTO("Akali", "", "", "Assassin"), new ChampionDTO("Aatrox", "", "", "Fighter") };
List<ChampionDTO> list = new List<ChampionDTO> { new ChampionDTO("Akali", "", "", "Assassin",""), new ChampionDTO("Aatrox", "", "", "Fighter","") };
IActionResult a = await api.Get(index: 0,size: 2);
@ -57,7 +58,7 @@ namespace Api_UT
[TestMethod]
public async Task Get_FilterAName_OkListOf5()
{
List<ChampionDTO> list = new List<ChampionDTO> { new ChampionDTO("Akali", "", "", "Assassin"), new ChampionDTO("Akshan", "", "", "Marksman") };
List<ChampionDTO> list = new List<ChampionDTO> { new ChampionDTO("Akali", "", "", "Assassin", ""), new ChampionDTO("Akshan", "", "", "Marksman", "") };
IActionResult a = await api.Get(name: "Ak");
@ -75,10 +76,12 @@ namespace Api_UT
public async Task Post_ValidChampion_Created()
{
ChampionsController api = new ChampionsController(new StubData());
IActionResult a = await api.Post(new ChampionDTO("nom","bio","icon", "Assassin"));
IActionResult a = await api.Post(new ChampionDTO("nom","bio","icon", "Assassin",""));
var action = (CreatedAtActionResult)a;
var champAction = action.Value as IEnumerable<ChampionDTO>;
Assert.IsNotNull(a);
ChampionDTO champ = new ChampionDTO("nom", "bio", "icon","Assassin");
Assert.IsTrue(champ.equals((ChampionDTO)((CreatedAtActionResult)a).Value));
ChampionDTO champ = new ChampionDTO("nom", "bio", "icon","Assassin", "");
Assert.IsTrue(champ.equals(other: (ChampionDTO)((CreatedAtActionResult)a).Value));
}
}

@ -25,7 +25,7 @@ namespace ConsoleApplication
Console.WriteLine("\n 9 - Quitter");
}
public static async void championMenu(IChampionsManager championsManager ) {
public static async Task championMenu(IChampionsManager championsManager ) {
string choix = "0";
while (choix != "9")
@ -36,7 +36,8 @@ namespace ConsoleApplication
switch (choix)
{
case "1":
//Console.WriteLine("# result : "+ await championsManager.GetNbItems());
var json = await championsManager.GetNbItems();
Console.WriteLine("# result : "+ json);
break;
case "2":
var list = await championsManager.GetItems(0, 10);

@ -5,17 +5,19 @@ namespace DTO
{
public class ChampionDTO
{
public ChampionDTO(string name, string bio, string icon, string championClassDTO)
public ChampionDTO(string name, string bio, string icon, string Class, string image)
{
Name = name;
Bio = bio;
Icon = icon;
Class = championClassDTO;
this.Class = Class;
Image = image;
}
public string Name { get; set; }
public string Bio { get; set; }
public string Icon { get; set; }
public string Image { get; set; }
public string Class { get; set; }
public bool equals(ChampionDTO other)

@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EntityFramework\EntityFramework.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>

@ -0,0 +1,43 @@
using EntityFramework;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DTO
{
public class RuneDTO
{
public RuneDTO(string name, string desc, RuneFamily family, LargeImage image, string icon)
{
Name = name;
Description = desc;
Family = family;
Image = image;
Icon = icon;
}
public string Name { get; set; }
public string Description { get; set; }
public RuneFamily Family { get; set; }
public string Icon { get; set; }
public LargeImage Image { get; set; }
public bool equals(RuneDTO other)
{
return other.Name == Name
&& other.Description == Description
&& other.Family == Family
&& other.Image == Image
&& other.Icon == Icon;
}
public string toString()
{
return Name + Description + Family.ToString();
}
}
}

@ -13,10 +13,16 @@ namespace DTO
public string Description { get; set; }
public string Icon { get; set; }
public SkinDTO(string name,string description,string icon) {
public string Image { get; set; }
public float Price { get; set; }
public SkinDTO(string name,string description,string icon,string image,float price) {
this.Name = name;
this.Description = description;
this.Icon = icon;
this.Image = image;
this.Price = price;
}
}

@ -0,0 +1,53 @@
using EntityFramework;
using EntityFramework.Manager;
using FluentAssertions;
using FluentAssertions.Primitives;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF_UT
{
[TestClass]
public class EFDataManagerChampionTest
{
[TestMethod]
public void Add_ValidChampion_Added()
{
IDataManager dataManager = new EFDataManager();
IChampionsManager championsManager = dataManager.ChampionsMgr;
var champ = championsManager.AddItem(new Champion("test"));
}
[TestMethod]
public async Task GetItemsByName_DefaultChamp_One()
{
var builder = WebApplication.CreateBuilder();
builder.Services.AddDbContext<LoLDBContextWithStub>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetService<LoLDBContextWithStub>();
context.Database.EnsureCreated();
}
IDataManager dataManager = new EFDataManager();
IChampionsManager championsManager = dataManager.ChampionsMgr;
var ak = (await championsManager.GetItemsByName("A", 0, 1)).First();
Assert.IsNotNull(ak);
Assert.AreEqual("Aatrox", ak.Name);
}
}
}

@ -23,11 +23,12 @@ namespace EF_UT
using (var context = new LoLDbContext(options))
{
ChampionEntity chewie = new ChampionEntity("Chewbacca", "", "");
ChampionEntity yoda = new ChampionEntity("Yoda", "", "");
ChampionEntity ewok = new ChampionEntity("Ewok", "", "");
ChampionEntity chewie = new ChampionEntity { Name = "Chewbacca", Bio = "", Icon = "" };
ChampionEntity yoda = new ChampionEntity{ Name = "Yoda", Bio = "", Icon = "" };
ChampionEntity ewok = new ChampionEntity{ Name = "Ewok", Bio = "", Icon = "" };
//SkinEntity defaulSkin = new SkinEntity("Skin Default", chewie);
//chewie.AddSkin(defaulSkin);
Console.WriteLine("Creates and inserts new Champion for tests");
context.Add(chewie);
context.Add(yoda);
@ -54,9 +55,9 @@ namespace EF_UT
//prepares the database with one instance of the context
using (var context = new LoLDbContext(options))
{
ChampionEntity chewie = new ChampionEntity("Chewbacca", "ewa", "");
ChampionEntity yoda = new ChampionEntity("Yoda", "wewo", "");
ChampionEntity ewok = new ChampionEntity("Ewok", "", "");
ChampionEntity chewie = new ChampionEntity{ Name = "Chewbacca", Bio = "ewa", Icon = "" };
ChampionEntity yoda = new ChampionEntity{ Name = "Yoda", Bio = "wewo", Icon = "" };
ChampionEntity ewok = new ChampionEntity{ Name = "Ewok", Bio = "", Icon = "" };
context.Add(chewie);
context.Add(yoda);

@ -32,14 +32,32 @@ namespace EntityFramework
//public ImmutableHashSet<Skill> Skills => skills.ToImmutableHashSet();
//private HashSet<Skill> skills = new HashSet<Skill>();
private ICollection<SkillEntity> Skills { get; set; }
public ICollection<SkillEntity> Skills { get; set; } = new Collection<SkillEntity>();
//public ReadOnlyCollection<SkinEntity> Skins { get; private set; }
//private List<SkinEntity> skins = new();
public ICollection<SkinEntity> skins { get; set; } = new Collection<SkinEntity>();
//public LargeImageEntity? Image { get; set; } ====> voir pour faire "plus propre" => créé une table pour l'entity Largeimage
public string? Image { get; set; }
// Pour le many to many Champion *<---->* RunePage
public ICollection<RunePageEntity> RunePageEntities{ get; set; }
public ChampionEntity(string name,string bio,string icon) {
this.Name = name;
this.Bio = bio;
this.Icon = icon;
Skills= new List<SkillEntity>();
}
/// <summary>
/// pas besoin de constructeur ! (sans lui, il est possible d'utiliser la syntaxe utilisé dans le stubbedbDBCOntext)
/// </summary>
/// <returns></returns>
//public ChampionEntity(string name,string bio,string icon) {
// this.Name = name;
// this.Bio = bio;
// this.Icon = icon;
// Skills= new List<SkillEntity>();
// //Skins = new ReadOnlyCollection<SkinEntity>(skins);
//}
public override string ToString()
{
@ -53,5 +71,15 @@ namespace EntityFramework
public void RemoveSkill(SkillEntity skill)
=> Skills.Remove(skill);
public bool AddSkin(SkinEntity skin)
{
if (skins.Contains(skin))
return false;
skins.Add(skin);
return true;
}
}
}

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -8,6 +8,14 @@
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Manager\EFDataManager.Champion.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Manager\EFDataManager.Champion.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.2" />
@ -18,6 +26,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
</ItemGroup>

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public enum EnumCategory
{
Major,
Minor1,
Minor2,
Minor3,
OtherMinor1,
OtherMinor2
}
}

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public enum EnumRuneFamily
{
Unknown,
Precision,
Domination
}
}

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class LargeImageEntity
{
public int Id { get; set; }
public string Base64 { get; set; }
//public LargeImageEntity(string base64)
//{
// Base64 = base64;
//}
}
}

@ -11,6 +11,16 @@ namespace EntityFramework
{
public DbSet<ChampionEntity> Champions { get; set; }
public DbSet<SkinEntity> Skins { get; set; }
public DbSet<SkillEntity> Skills { get; set; }
public DbSet<LargeImageEntity> Image { get; set; }
public DbSet<RuneEntity> Rune { get; set; }
public DbSet<RunePageEntity> RunePage { get; set; }
public LoLDbContext()
{ }
@ -30,14 +40,15 @@ namespace EntityFramework
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ChampionEntity>().HasKey(entity => entity.Name);
modelBuilder.Entity<ChampionEntity>().ToTable("Champion");
modelBuilder.Entity<ChampionEntity>().ToTable("Champions");
//modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Id)
// .ValueGeneratedOnAdd();
modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Name)
.IsRequired()
.HasMaxLength(50);
.HasMaxLength(50)
.ValueGeneratedOnAdd();
modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Bio)
.HasMaxLength(500)
@ -46,7 +57,83 @@ namespace EntityFramework
modelBuilder.Entity<ChampionEntity>().Property(entity => entity.Icon)
.IsRequired();
/// One to many
/// ChampionEntity 1 ---> * SkinEntity
//création de la table Skin
modelBuilder.Entity<SkinEntity>().HasKey(skin => skin.Name); //définition de la clé primaire
modelBuilder.Entity<SkinEntity>().Property(skin => skin.Name)
.ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion
// Add the shadow property to the model
modelBuilder.Entity<SkinEntity>()
.Property<string>("ChampionEntityForeignKey");
// Use the shadow property as a foreign key
modelBuilder.Entity<SkinEntity>()
.HasOne(skin => skin.Champion)
.WithMany(champion => champion.skins)
.HasForeignKey("ChampionEntityForeignKey");
/// One to many
/// ChampionEntity ---> * SkillEntity
//création de la table ChampionEntity
//modelBuilder.Entity<ChampionEntity>().HasKey(c => c.Name); //définition de la clé primaire
//modelBuilder.Entity<ChampionEntity>().Property(c => c.Name)
// .ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion
//création de la table SkillEntity
modelBuilder.Entity<SkillEntity>().HasKey(s => s.Name); //définition de la clé primaire
modelBuilder.Entity<SkillEntity>().Property(s => s.Name)
.ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion
// Add the shadow property to the model
modelBuilder.Entity<SkillEntity>()
.Property<string>("ChampionEntityToSkillForeignKey");
// Use the shadow property as a foreign key
modelBuilder.Entity<SkillEntity>()
.HasOne(s => s.Champion)
.WithMany(c => c.Skills)
.HasForeignKey("ChampionEntityToSkillForeignKey");
/// Many to Many ChampionEntity - RunePageEntity
modelBuilder.Entity<RunePageEntity>().HasKey(entity => entity.Name);
modelBuilder.Entity<RunePageEntity>().HasKey(entity => entity.Name);
modelBuilder.Entity<RunePageEntity>().ToTable("RunePage");
// Use the shadow property as a foreign key
modelBuilder.Entity<RunePageEntity>()
.HasMany(r => r.Champion)
.WithMany(c => c.RunePageEntities);
//.HasForeignKey("AlbumForeignKey");
modelBuilder.Entity<ChampionEntity>()
.HasMany(c => c.RunePageEntities)
.WithMany(r => r.Champion);
//.HasForeignKey("AlbumForeignKey");
//création de la table RuneEntity
modelBuilder.Entity<RuneEntity>().HasKey(r => r.Name); //définition de la clé primaire
modelBuilder.Entity<RuneEntity>().Property(r => r.Name)
.ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion
modelBuilder.Entity<RuneEntity>()
.Property<string>("RuneForeignKey");
modelBuilder.Entity<RuneEntity>()
.HasOne(r => r.RunePage)
.WithMany(rp => rp.Runes)
.HasForeignKey("RuneForeignKey");
}
}

@ -0,0 +1,186 @@
using EntityFramework.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Manager
{
public partial class EFDataManager
{
public class ChampionsManager : IChampionsManager
{
private readonly EFDataManager parent;
public ChampionsManager(EFDataManager parent)
{
this.parent = parent;
}
public async Task<Champion?> AddItem(Champion? item)
{
using(var context = new LoLDBContextWithStub())
{
if (item != null)
{
context.Add(item.ToEntity());
context.SaveChanges();
return item;
}
else
{
throw new Exception();
}
}
}
public async Task<bool> DeleteItem(Champion? item)
{
using (var context = new LoLDBContextWithStub())
{
var champ = context.Champions.Select(c => c == item.ToEntity());
if(champ.Count()<1)
{
return false;
}
context.Champions.Remove(item.ToEntity());
context.SaveChanges();
return true;
}
}
public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using(var context = new LoLDBContextWithStub() )
{
var champ = context.Champions.ToArray();
if (descending == false)
{
return champ.ToList().Skip(index * count).Take(count).Select(c => c.ToChampion()).OrderBy(c => c.Name);
}
else
{
return champ.ToList().Skip(index * count).Take(count).Select(c => c.ToChampion()).OrderByDescending(c => c.Name);
}
}
}
public Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsByClass(Model.ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using (var context = new LoLDBContextWithStub())
{
var champ = context.Champions.Where(c => c.Name.Contains(substring)).AsEnumerable();
if (descending == false)
{
return champ.Select(c => c.ToChampion()).ToList().Skip(index * count).Take(count).OrderBy(c=> c.Name);
}
else
{
return champ.Select(c => c.ToChampion()).ToList().Skip(index*count).Take(count).OrderByDescending(c => c.Name);
}
}
}
public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using(var context = new LoLDBContextWithStub())
{
var champ = context.Champions.Where(c => c.Skills.Any(c => c.Name.Contains(skill)));
if (descending.Equals(false))
{
return champ.Select(c=> c.ToChampion()).ToList().Skip(index * count).Take(count).OrderBy(c => c.Name);
}
else
{
return champ.Select(c => c.ToChampion()).ToList().Skip(index * count).Take(count).OrderByDescending(c => c.Name);
}
}
}
public async Task<int> GetNbItems()
{
using(var context = new LoLDBContextWithStub())
{
return context.Champions.Count();
}
}
public Task<int> GetNbItemsByCharacteristic(string charName)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByClass(Model.ChampionClass championClass)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByName(string substring)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByRunePage(RunePage? runePage)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(Skill? skill)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(string skill)
{
throw new NotImplementedException();
}
public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
{
using(var context = new LoLDBContextWithStub())
{
if (oldItem != null && newItem != null)
{
var champ = context.Champions.Where(c => c == oldItem.ToEntity()).First();
champ = newItem.ToEntity();
context.SaveChanges();
return newItem;
}
else { throw new Exception(); }
}
}
}
}
}

@ -0,0 +1,85 @@
using EntityFramework.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Manager
{
public partial class EFDataManager
{
public class SkinsManager : ISkinsManager
{
private readonly EFDataManager parent;
public SkinsManager(EFDataManager parent)
{
this.parent = parent;
}
public Task<Skin?> AddItem(Skin? item)
{
throw new NotImplementedException();
}
public Task<bool> DeleteItem(Skin? item)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Skin?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<Skin?>> GetItemsByChampion(Champion? champion, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
using (var context = new LoLDBContextWithStub())
{
var skins = context.Skins.Where(c => c.Champion.Equals(champion)).ToList();
if (descending == false)
{
return skins.Select(c => c.ToSkin()).ToList().Skip(index * count).Take(count).OrderBy(c => c.Name);
}
else
{
return skins.Select(c => c.ToSkin()).ToList().Skip(index * count).Take(count).OrderByDescending(c => c.Name);
}
}
}
public Task<IEnumerable<Skin?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<int> GetNbItems()
{
throw new NotImplementedException();
}
public async Task<int> GetNbItemsByChampion(Champion? champion)
{
using(var context = new LoLDBContextWithStub())
{
return context.Skins.Where(c => c.Champion.Equals(champion.ToEntity())).Count();
}
}
public Task<int> GetNbItemsByName(string substring)
{
throw new NotImplementedException();
}
public Task<Skin?> UpdateItem(Skin? oldItem, Skin? newItem)
{
throw new NotImplementedException();
}
}
}
}

@ -0,0 +1,25 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Manager
{
public partial class EFDataManager : IDataManager
{
public EFDataManager() {
ChampionsMgr = new ChampionsManager(this);
SkinsMgr = new SkinsManager(this);
}
public IChampionsManager ChampionsMgr { get; }
public ISkinsManager SkinsMgr { get; }
public IRunesManager RunesMgr { get; }
public IRunePagesManager RunePagesMgr { get; }
}
}

@ -10,7 +10,13 @@ namespace EntityFramework.Mapper
public static class ChampionMapper
{
public static ChampionEntity ToEntity(this Champion champion) {
return new ChampionEntity(champion.Name, champion.Bio, champion.Icon);
return new ChampionEntity { Name = champion.Name, Bio = champion.Bio, Icon = champion.Icon };
}
public static Champion ToChampion(this ChampionEntity champion)
{
return new Champion(champion.Name,bio: champion.Bio,icon: champion.Icon);
}
}
}

@ -0,0 +1,24 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework.Mapper
{
public static class SkinMapper
{
public static SkinEntity ToEntity(this Skin skin)
{
return new SkinEntity { Champion = skin.Champion.ToEntity(), Description = skin.Description, Icon = skin.Icon, Image = skin.Image.Base64, Name = skin.Name, Price = skin.Price };
}
public static Skin ToSkin(this SkinEntity entity)
{
return new Skin(entity.Name,entity.Champion.ToChampion(),price: entity.Price,icon: entity.Icon, image: entity.Image,description: entity.Description);
}
}
}

@ -1,83 +0,0 @@
// <auto-generated />
using EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace EntityFramework.Migrations
{
[DbContext(typeof(LoLDBContextWithStub))]
[Migration("20230312170120_stubMig")]
partial class stubMig
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
modelBuilder.Entity("EntityFramework.ChampionEntity", b =>
{
b.Property<string>("Name")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<string>("Bio")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("string")
.HasColumnName("Bio");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Name");
b.ToTable("Champion", (string)null);
b.HasData(
new
{
Name = "Akali",
Bio = "",
Icon = ""
},
new
{
Name = "Aatrox",
Bio = "",
Icon = ""
},
new
{
Name = "Ahri",
Bio = "",
Icon = ""
},
new
{
Name = "Akshan",
Bio = "",
Icon = ""
},
new
{
Name = "Bard",
Bio = "",
Icon = ""
},
new
{
Name = "Alistar",
Bio = "",
Icon = ""
});
});
#pragma warning restore 612, 618
}
}
}

@ -1,49 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace EntityFramework.Migrations
{
/// <inheritdoc />
public partial class stubMig : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Champion",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
Bio = table.Column<string>(type: "string", maxLength: 500, nullable: false),
Icon = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Champion", x => x.Name);
});
migrationBuilder.InsertData(
table: "Champion",
columns: new[] { "Name", "Bio", "Icon" },
values: new object[,]
{
{ "Aatrox", "", "" },
{ "Ahri", "", "" },
{ "Akali", "", "" },
{ "Akshan", "", "" },
{ "Alistar", "", "" },
{ "Bard", "", "" }
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Champion");
}
}
}

@ -0,0 +1,225 @@
// <auto-generated />
using EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace EntityFramework.Migrations
{
[DbContext(typeof(LoLDbContext))]
[Migration("20230325150121_MigrSkill")]
partial class MigrSkill
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
modelBuilder.Entity("ChampionEntityRunePageEntity", b =>
{
b.Property<string>("ChampionName")
.HasColumnType("TEXT");
b.Property<string>("RunePageEntitiesName")
.HasColumnType("TEXT");
b.HasKey("ChampionName", "RunePageEntitiesName");
b.HasIndex("RunePageEntitiesName");
b.ToTable("ChampionEntityRunePageEntity");
});
modelBuilder.Entity("EntityFramework.ChampionEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<string>("Bio")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("string")
.HasColumnName("Bio");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Image")
.HasColumnType("TEXT");
b.HasKey("Name");
b.ToTable("Champions", (string)null);
});
modelBuilder.Entity("EntityFramework.LargeImageEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Base64")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Image");
});
modelBuilder.Entity("EntityFramework.RuneEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("RuneForeignKey")
.HasColumnType("TEXT");
b.HasKey("Name");
b.HasIndex("RuneForeignKey");
b.ToTable("Rune");
});
modelBuilder.Entity("EntityFramework.RunePageEntity", b =>
{
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("RuneName")
.HasColumnType("TEXT");
b.HasKey("Name");
b.HasIndex("RuneName");
b.ToTable("RunePage", (string)null);
});
modelBuilder.Entity("EntityFramework.SkillEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("ChampionEntityToSkillForeignKey")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Name");
b.HasIndex("ChampionEntityToSkillForeignKey");
b.ToTable("Skills");
});
modelBuilder.Entity("EntityFramework.SkinEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("ChampionEntityForeignKey")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Image")
.HasColumnType("TEXT");
b.Property<float>("Price")
.HasColumnType("REAL");
b.HasKey("Name");
b.HasIndex("ChampionEntityForeignKey");
b.ToTable("Skins");
});
modelBuilder.Entity("ChampionEntityRunePageEntity", b =>
{
b.HasOne("EntityFramework.ChampionEntity", null)
.WithMany()
.HasForeignKey("ChampionName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("EntityFramework.RunePageEntity", null)
.WithMany()
.HasForeignKey("RunePageEntitiesName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("EntityFramework.RuneEntity", b =>
{
b.HasOne("EntityFramework.RunePageEntity", "RunePage")
.WithMany("Runes")
.HasForeignKey("RuneForeignKey");
b.Navigation("RunePage");
});
modelBuilder.Entity("EntityFramework.RunePageEntity", b =>
{
b.HasOne("EntityFramework.RuneEntity", "Rune")
.WithMany()
.HasForeignKey("RuneName");
b.Navigation("Rune");
});
modelBuilder.Entity("EntityFramework.SkillEntity", b =>
{
b.HasOne("EntityFramework.ChampionEntity", "Champion")
.WithMany("Skills")
.HasForeignKey("ChampionEntityToSkillForeignKey");
b.Navigation("Champion");
});
modelBuilder.Entity("EntityFramework.SkinEntity", b =>
{
b.HasOne("EntityFramework.ChampionEntity", "Champion")
.WithMany("skins")
.HasForeignKey("ChampionEntityForeignKey");
b.Navigation("Champion");
});
modelBuilder.Entity("EntityFramework.ChampionEntity", b =>
{
b.Navigation("Skills");
b.Navigation("skins");
});
modelBuilder.Entity("EntityFramework.RunePageEntity", b =>
{
b.Navigation("Runes");
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,197 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace EntityFramework.Migrations
{
/// <inheritdoc />
public partial class MigrSkill : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Champions",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
Bio = table.Column<string>(type: "string", maxLength: 500, nullable: false),
Icon = table.Column<string>(type: "TEXT", nullable: false),
Image = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Champions", x => x.Name);
});
migrationBuilder.CreateTable(
name: "Image",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Base64 = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Image", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Skills",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: false),
ChampionEntityToSkillForeignKey = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Skills", x => x.Name);
table.ForeignKey(
name: "FK_Skills_Champions_ChampionEntityToSkillForeignKey",
column: x => x.ChampionEntityToSkillForeignKey,
principalTable: "Champions",
principalColumn: "Name");
});
migrationBuilder.CreateTable(
name: "Skins",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: true),
Icon = table.Column<string>(type: "TEXT", nullable: false),
Image = table.Column<string>(type: "TEXT", nullable: true),
Price = table.Column<float>(type: "REAL", nullable: false),
ChampionEntityForeignKey = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Skins", x => x.Name);
table.ForeignKey(
name: "FK_Skins_Champions_ChampionEntityForeignKey",
column: x => x.ChampionEntityForeignKey,
principalTable: "Champions",
principalColumn: "Name");
});
migrationBuilder.CreateTable(
name: "ChampionEntityRunePageEntity",
columns: table => new
{
ChampionName = table.Column<string>(type: "TEXT", nullable: false),
RunePageEntitiesName = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChampionEntityRunePageEntity", x => new { x.ChampionName, x.RunePageEntitiesName });
table.ForeignKey(
name: "FK_ChampionEntityRunePageEntity_Champions_ChampionName",
column: x => x.ChampionName,
principalTable: "Champions",
principalColumn: "Name",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Rune",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
RuneForeignKey = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Rune", x => x.Name);
});
migrationBuilder.CreateTable(
name: "RunePage",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
RuneName = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_RunePage", x => x.Name);
table.ForeignKey(
name: "FK_RunePage_Rune_RuneName",
column: x => x.RuneName,
principalTable: "Rune",
principalColumn: "Name");
});
migrationBuilder.CreateIndex(
name: "IX_ChampionEntityRunePageEntity_RunePageEntitiesName",
table: "ChampionEntityRunePageEntity",
column: "RunePageEntitiesName");
migrationBuilder.CreateIndex(
name: "IX_Rune_RuneForeignKey",
table: "Rune",
column: "RuneForeignKey");
migrationBuilder.CreateIndex(
name: "IX_RunePage_RuneName",
table: "RunePage",
column: "RuneName");
migrationBuilder.CreateIndex(
name: "IX_Skills_ChampionEntityToSkillForeignKey",
table: "Skills",
column: "ChampionEntityToSkillForeignKey");
migrationBuilder.CreateIndex(
name: "IX_Skins_ChampionEntityForeignKey",
table: "Skins",
column: "ChampionEntityForeignKey");
migrationBuilder.AddForeignKey(
name: "FK_ChampionEntityRunePageEntity_RunePage_RunePageEntitiesName",
table: "ChampionEntityRunePageEntity",
column: "RunePageEntitiesName",
principalTable: "RunePage",
principalColumn: "Name",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Rune_RunePage_RuneForeignKey",
table: "Rune",
column: "RuneForeignKey",
principalTable: "RunePage",
principalColumn: "Name");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Rune_RunePage_RuneForeignKey",
table: "Rune");
migrationBuilder.DropTable(
name: "ChampionEntityRunePageEntity");
migrationBuilder.DropTable(
name: "Image");
migrationBuilder.DropTable(
name: "Skills");
migrationBuilder.DropTable(
name: "Skins");
migrationBuilder.DropTable(
name: "Champions");
migrationBuilder.DropTable(
name: "RunePage");
migrationBuilder.DropTable(
name: "Rune");
}
}
}

@ -1,80 +0,0 @@
// <auto-generated />
using EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace EntityFramework.Migrations
{
[DbContext(typeof(LoLDBContextWithStub))]
partial class LoLDBContextWithStubModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
modelBuilder.Entity("EntityFramework.ChampionEntity", b =>
{
b.Property<string>("Name")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<string>("Bio")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("string")
.HasColumnName("Bio");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Name");
b.ToTable("Champion", (string)null);
b.HasData(
new
{
Name = "Akali",
Bio = "",
Icon = ""
},
new
{
Name = "Aatrox",
Bio = "",
Icon = ""
},
new
{
Name = "Ahri",
Bio = "",
Icon = ""
},
new
{
Name = "Akshan",
Bio = "",
Icon = ""
},
new
{
Name = "Bard",
Bio = "",
Icon = ""
},
new
{
Name = "Alistar",
Bio = "",
Icon = ""
});
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,222 @@
// <auto-generated />
using EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace EntityFramework.Migrations
{
[DbContext(typeof(LoLDbContext))]
partial class LoLDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
modelBuilder.Entity("ChampionEntityRunePageEntity", b =>
{
b.Property<string>("ChampionName")
.HasColumnType("TEXT");
b.Property<string>("RunePageEntitiesName")
.HasColumnType("TEXT");
b.HasKey("ChampionName", "RunePageEntitiesName");
b.HasIndex("RunePageEntitiesName");
b.ToTable("ChampionEntityRunePageEntity");
});
modelBuilder.Entity("EntityFramework.ChampionEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<string>("Bio")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("string")
.HasColumnName("Bio");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Image")
.HasColumnType("TEXT");
b.HasKey("Name");
b.ToTable("Champions", (string)null);
});
modelBuilder.Entity("EntityFramework.LargeImageEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Base64")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Image");
});
modelBuilder.Entity("EntityFramework.RuneEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("RuneForeignKey")
.HasColumnType("TEXT");
b.HasKey("Name");
b.HasIndex("RuneForeignKey");
b.ToTable("Rune");
});
modelBuilder.Entity("EntityFramework.RunePageEntity", b =>
{
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("RuneName")
.HasColumnType("TEXT");
b.HasKey("Name");
b.HasIndex("RuneName");
b.ToTable("RunePage", (string)null);
});
modelBuilder.Entity("EntityFramework.SkillEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("ChampionEntityToSkillForeignKey")
.HasColumnType("TEXT");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Name");
b.HasIndex("ChampionEntityToSkillForeignKey");
b.ToTable("Skills");
});
modelBuilder.Entity("EntityFramework.SkinEntity", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("ChampionEntityForeignKey")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("Icon")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Image")
.HasColumnType("TEXT");
b.Property<float>("Price")
.HasColumnType("REAL");
b.HasKey("Name");
b.HasIndex("ChampionEntityForeignKey");
b.ToTable("Skins");
});
modelBuilder.Entity("ChampionEntityRunePageEntity", b =>
{
b.HasOne("EntityFramework.ChampionEntity", null)
.WithMany()
.HasForeignKey("ChampionName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("EntityFramework.RunePageEntity", null)
.WithMany()
.HasForeignKey("RunePageEntitiesName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("EntityFramework.RuneEntity", b =>
{
b.HasOne("EntityFramework.RunePageEntity", "RunePage")
.WithMany("Runes")
.HasForeignKey("RuneForeignKey");
b.Navigation("RunePage");
});
modelBuilder.Entity("EntityFramework.RunePageEntity", b =>
{
b.HasOne("EntityFramework.RuneEntity", "Rune")
.WithMany()
.HasForeignKey("RuneName");
b.Navigation("Rune");
});
modelBuilder.Entity("EntityFramework.SkillEntity", b =>
{
b.HasOne("EntityFramework.ChampionEntity", "Champion")
.WithMany("Skills")
.HasForeignKey("ChampionEntityToSkillForeignKey");
b.Navigation("Champion");
});
modelBuilder.Entity("EntityFramework.SkinEntity", b =>
{
b.HasOne("EntityFramework.ChampionEntity", "Champion")
.WithMany("skins")
.HasForeignKey("ChampionEntityForeignKey");
b.Navigation("Champion");
});
modelBuilder.Entity("EntityFramework.ChampionEntity", b =>
{
b.Navigation("Skills");
b.Navigation("skins");
});
modelBuilder.Entity("EntityFramework.RunePageEntity", b =>
{
b.Navigation("Runes");
});
#pragma warning restore 612, 618
}
}
}

@ -1,12 +1,16 @@
// See https://aka.ms/new-console-template for more information
using EntityFramework;
using EntityFramework.Manager;
using Microsoft.EntityFrameworkCore;
using Model;
using System.Buffers.Text;
using( var context = new LoLDbContext())
using ( var context = new LoLDbContext())
{
context.Add(new ChampionEntity("test","test","test") );
//context.Add(new ChampionEntity{ Name = "test", Bio = "test", Icon = "test" } );
context.SaveChanges();
ChampionEntity champ = context.Find<ChampionEntity>(1);
ChampionEntity champ = context.Find<ChampionEntity>("Akali");
if( champ != null)
{
@ -20,18 +24,126 @@ using( var context = new LoLDbContext())
}
//Test BDD Skills
ChampionEntity champSkill = new ChampionEntity("nomSkill", "bioSkill", "iconSkill");
ChampionEntity champSkill = new ChampionEntity { Name="nomSkill", Bio="bioSkill", Icon="iconSkill" };
SkillEntity s1 = new SkillEntity("Skill1", "desc", SkillType.Unknown);
SkillEntity s2 = new SkillEntity("Skill2", "desc2", SkillType.Ultimate);
SkillEntity s3 = new SkillEntity("Skill3", "desc3", SkillType.Passive);
//SkillEntity s1 = new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown };
SkillEntity s2 = new SkillEntity { Name="Skill2", Description="desc2", Type= EntityFramework.SkillType.Ultimate };
SkillEntity s3 = new SkillEntity { Name = "Skill3", Description = "desc3", Type = EntityFramework.SkillType.Passive };
champSkill.AddSkill(s1);
champSkill.AddSkill(new SkillEntity { Name = "Skill1", Description = "desc", Type = EntityFramework.SkillType.Unknown });
champSkill.AddSkill(s2);
champSkill.AddSkill(s3);
context.Add(champSkill);
context.SaveChanges();
}
IDataManager dataManager = new EFDataManager();
IChampionsManager championsManager = dataManager.ChampionsMgr;
IEnumerable<Champion?> champions = await championsManager.GetItemsByName("A", 0, 1);
//Console.WriteLine(champions.First().Name);
//using ( var context = new LoLDbContext())
//{
// //context.Add(new ChampionEntity{ Name = "test", Bio = "test", Icon = "test" } );
// context.SaveChanges();
// ChampionEntity champ = context.Find<ChampionEntity>("Akali");
// if( champ != null)
// {
// Console
// .WriteLine(champ.ToString());
// }
// else
// {
// Console.WriteLine("Not Found");
// }
// //Test BDD Skills
// ChampionEntity champSkill = new ChampionEntity { Name="nomSkill", Bio="bioSkill", Icon="iconSkill" };
// //SkillEntity s1 = new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown };
// SkillEntity s2 = new SkillEntity { Name="Skill2", Description="desc2", Type=SkillType.Ultimate };
// SkillEntity s3 = new SkillEntity { Name = "Skill3", Description = "desc3", Type = SkillType.Passive };
// champSkill.AddSkill(new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown });
// champSkill.AddSkill(s2);
// champSkill.AddSkill(s3);
// context.Add(champSkill);
// context.SaveChanges();
// //OneToMany
// Console.WriteLine("Champions : ");
// foreach (var champi in context.Champions.Include(a => a.skins))
// {
// Console.WriteLine($"\t{champi.Name} : {champi.Bio}");
// foreach (var s in champi.skins)
// {
// Console.WriteLine($"\t\t{s.Name}");
// }
// }
// Console.WriteLine();
// Console.WriteLine("Skin :");
// foreach (var s in context.Skins)
// {
// Console.WriteLine($"\t{s.Name}: {s.Description} (Champion : {s.Champion.Name})");
// }
Console.WriteLine("\nAjout d'un Champion et 6 Skins...\n");
ChampionEntity captainMarvel = new ChampionEntity { Name = "Captain Marvel", Bio = "Mais que fait un avenger ici ??", Icon = "Icon.png" };
SkinEntity[] skins = { new SkinEntity {Name = "La Fiesta", Champion = captainMarvel},
new SkinEntity { Name = "Five Hundred Miles High", Champion = captainMarvel },
new SkinEntity { Name = "Captain Marvel", Champion = captainMarvel },
new SkinEntity { Name = "Time's Lie", Champion = captainMarvel },
new SkinEntity { Name = "Lush Life", Champion = captainMarvel },
new SkinEntity { Name = "Day Waves", Champion = captainMarvel }
};
foreach (var s in skins)
{
captainMarvel.skins.Add(s);
}
context.Add(captainMarvel);
context.SaveChanges();
//OnetoMany Skill
ChampionEntity Levram = new ChampionEntity { Name = "Captain Levram", Bio="bio", Icon="/img" };
SkillEntity[] morceaux = { new SkillEntity { Name = "La Fiesta", Description="SkillDesc", Type=EntityFramework.SkillType.Unknown, Champion= Levram },
new SkillEntity { Name = "berserk", Description="SkillDesc1", Type=EntityFramework.SkillType.Unknown, Champion= Levram },
new SkillEntity { Name = "taunt", Description = "SkillDesc2", Type = EntityFramework.SkillType.Unknown, Champion = Levram },
new SkillEntity { Name = "fear", Description = "SkillDesc3", Type = EntityFramework.SkillType.Unknown, Champion = Levram },
new SkillEntity { Name = "flashHeal", Description = "SkillDesc4", Type = EntityFramework.SkillType.Unknown, Champion = Levram },
new SkillEntity { Name = "bubbuletp", Description = "SkillDesc5", Type = EntityFramework.SkillType.Unknown, Champion = Levram }
};
foreach (var m in morceaux)
{
Levram.Skills.Add(m);
}
context.Add(Levram);
context.SaveChanges();
var r1 = new RuneEntity { Name = "Rune1", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") };
var r2 = new RuneEntity { Name = "Rune2", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") };
var corichard = new ChampionEntity { Name = "Corichard", Bio = "biobio", Icon = "Icon.png" };
var pintrand = new ChampionEntity { Name = "Pintrand", Bio = "biobio", Icon = "Icon.png" };
var rp1 = new RunePageEntity { Name = "RP1", Rune = new RuneEntity { Name = "aa", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") }, Champion = new List<ChampionEntity> { corichard } };
var rp2 = new RunePageEntity { Name = "RP2", Rune = new RuneEntity{ Name = "aaa", Description = "aaa", Family = EnumRuneFamily.Domination, Image = new LargeImage("base") }, Champion = new List<ChampionEntity> { pintrand } };
context.Rune.AddRange(new[] { r1, r2 });
context.Champions.AddRange(new[] { corichard, pintrand });
context.RunePage.AddRange(new[] { rp1, rp2 });
context.SaveChanges();
}

@ -0,0 +1,28 @@
using Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
//[Table("Rune")]
public class RuneEntity
{
[Key]
public string Name;
public string Description;
public EnumRuneFamily Family;
public LargeImage Image;
//OtM
public RunePageEntity RunePage { get; set; }
}
}

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Model.RunePage;
namespace EntityFramework
{
public class RunePageEntity
{
[Key]
public string Name { get; set; }
public RuneEntity? Rune { get; set; }
//? voir si cela pause probleme
//public Dictionary<EnumCategory, Rune> Dico = new Dictionary<EnumCategory, Rune>();
// One to many pour l'instant, voir si on retransforme en dico :
public ICollection<RuneEntity> Runes { get; set; }
// Pour le many to many Champion *<---->* RunePage
public ICollection<ChampionEntity> Champion{ get; set; }
public void CheckRunes(EnumCategory newRuneCategory){}
public void CheckFamilies(EnumCategory cat1, EnumCategory cat2){}
public void UpdateMajorFamily(EnumCategory minor, bool expectedValue){}
}
}

@ -10,42 +10,48 @@ namespace EntityFramework
public class SkillEntity
{
public SkillType Type { get; private set; }
public SkillType Type { get; set; }
[Key]
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 Name { get; 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 string Description { get; set; }
//public string Description
//{
// get => description;
// set
// {
// if (string.IsNullOrWhiteSpace(value))
// {
// description = "";
// return;
// }
// description = value;
// }
//}
//private string description = "";
public SkillEntity(string Name, string Description, SkillType Type) {
this.name = Name;
this.Description = Description;
this.Type = Type;
}
//public SkillEntity(string Name, string Description, SkillType Type) {
// this.name = Name;
// this.Description = Description;
// this.Type = Type;
//}
// One to many with champion :
public ChampionEntity Champion { get; set; }
}
}

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class SkinEntity //ONE TO MANY
{
[Key]
public string? Name { get; set; }
public string? Description { get; set; }
//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 LargeImageEntity Image { get; set; }
public string? Image { get; set; }
public float Price { get; set; }
public ChampionEntity Champion { get; set; }
//public ChampionEntity Champion
//{
// get => champion;
// private init
// {
// if (value == null)
// throw new ArgumentNullException("A skill can't have a null champion");
// champion = value;
// }
//}
//private readonly ChampionEntity champion = null!;
//public SkinEntity(string name, ChampionEntity champion, float price = 0.0f, string icon = "", string image = "", string description = "")
//{
// Name = name;
// Champion = champion;
// //Champion.AddSkin(this);
// Price = price;
// Icon = icon;
// Image = new LargeImageEntity(image);
// Description = description;
//}
}
}

@ -0,0 +1,84 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFramework
{
public class StubbedContext : LoLDbContext
{
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// optionsBuilder.EnableSensitiveDataLogging();
//}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
ChampionEntity corichard = new ChampionEntity { Name = "Corichard", Bio = "biobiobiobio", Icon = "/a/a/a/a" };
ChampionEntity pintrand = new ChampionEntity { Name = "Pintrand", Bio = "mimimimimim", Icon = "/small.png" };
RuneEntity r1 = new RuneEntity { Name = "FirstRune", Description = "desc", Family = EnumRuneFamily.Domination };
RuneEntity r2 = new RuneEntity { Name = "SecondRune", Description = "desc", Family = EnumRuneFamily.Unknown };
//ChampionEntity corichard = new ChampionEntity() { Name = "Corichard", Bio = "biobiobiobio", Icon = "/a/a/a/a", Image = new LargeImageEntity { Base64 = "base" } };
//ChampionEntity pintrand = new ChampionEntity { Name = "Pintrand", Bio = "mimimimimim", Icon = "/small.png", Image = new LargeImageEntity { Base64 = "base" } };
modelBuilder.Entity<ChampionEntity>().HasData(corichard, pintrand);
modelBuilder.Entity<SkinEntity>().HasData(new { Name = "aaaa", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon="/Icon.png", Price=10.0f },
new { Name = "skin", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "bo", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "Joulie", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "Radiance", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "void", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "Radiance", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "void", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "DarkTheme", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "gold", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f },
new { Name = "ruby", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f }
);
//Skills
modelBuilder.Entity<SkillEntity>().HasData(new { Name="Skill", Description="Desc", Type= SkillType.Basic, ChampionEntityToSkillForeignKey= "Corichard" },
new { Name = "Skill2", Description = "Desc", Type = SkillType.Basic, ChampionEntityToSkillForeignKey = "Corichard" },
new { Name = "Skill3", Description = "Desc", Type = SkillType.Passive, ChampionEntityToSkillForeignKey = "Corichard" },
new { Name = "Skill4", Description = "Desc", Type = SkillType.Unknown, ChampionEntityToSkillForeignKey = "Corichard" },
new { Name = "Skill5", Description = "Desc", Type = SkillType.Basic, ChampionEntityToSkillForeignKey = "Corichard" },
new { Name = "Skill6", Description = "Desc", Type = SkillType.Basic, ChampionEntityToSkillForeignKey = "Corichard" },
new { Name = "Skill10", Description = "Desc", Type = SkillType.Basic, ChampionEntityToSkillForeignKey = "Pintrand" },
new { Name = "Skill11", Description = "Desc", Type = SkillType.Unknown, ChampionEntityToSkillForeignKey = "Pintrand" },
new { Name = "Skill12", Description = "Desc", Type = SkillType.Passive, ChampionEntityToSkillForeignKey = "Pintrand" },
new { Name = "Skill13", Description = "Desc", Type = SkillType.Basic, ChampionEntityToSkillForeignKey = "Pintrand" },
new { Name = "Skill14", Description = "Desc", Type = SkillType.Basic, ChampionEntityToSkillForeignKey = "Pintrand" }
);
modelBuilder.Entity<RunePageEntity>().HasData(new { Name = "RP1", Rune = r1, Champion = corichard},
new { Name = "RP2", Rune = r2, Champion = pintrand}
);
RunePageEntity rp11 = new RunePageEntity { Name = "rp11"};
RunePageEntity rp21 = new RunePageEntity { Name = "rp21"};
modelBuilder.Entity<RunePageEntity>().HasData(rp11, rp21);
modelBuilder.Entity<RuneEntity>().HasData(new { Name = "Rune", Description = "Desc", Famille = EnumRuneFamily.Domination, RuneForeignKey = "rp11" },
new{Name = "Rune2", Description = "Desc",Famille = EnumRuneFamily.Domination,RuneForeignKey = "rp11"},
new { Name = "Rune3", Description = "Desc", Famille = EnumRuneFamily.Domination, RuneForeignKey = "rp21" },
new { Name = "Rune4", Description = "Desc", Famille = EnumRuneFamily.Domination, RuneForeignKey = "rp21" }
);
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClient
{
public class ChampionCountResponse
{
public int Result { get; set; }
public int Id { get; set; }
public object Exception { get; set; }
public int Status { get; set; }
public bool IsCanceled { get; set; }
public bool IsCompleted { get; set; }
public bool IsCompletedSuccessfully { get; set; }
public int CreationOptions { get; set; }
public object AsyncState { get; set; }
public bool IsFaulted { get; set; }
}
}

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\API_LoL\API_LoL.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,144 @@
using DTO;
using DTO.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace HttpClient
{
public partial class HttpClientManager
{
public class ChampionManager : IChampionsManager
{
private readonly HttpClientManager parent;
private System.Net.Http.HttpClient httpc;
public string BaseAddress;
public ChampionManager(HttpClientManager parent, System.Net.Http.HttpClient httpc) {
this.httpc = httpc;
this.parent = parent;
}
public async Task<Champion?> AddItem(Champion? item) //return le champion ajouté, null sinon ?
{
if(item==null) throw new ArgumentNullException("item is null");
var response = await httpc.PostAsJsonAsync("v1/Champions?Name = " + item.Name, item);
return response.IsSuccessStatusCode ? item : null;
}
public async Task<bool> DeleteItem(Champion? item)
{
HttpResponseMessage response = await httpc.DeleteAsync("v1/Champions?Name=" + item.Name);
_ = response.StatusCode;
return response.IsSuccessStatusCode;
}
public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
{
IEnumerable<ChampionDTO> champdto = await httpc.GetFromJsonAsync<IEnumerable<ChampionDTO>>("v1/Champions?index="+index+"&size="+count);
return champdto.Select(c => c.ToChampion());
}
public Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
return httpc.GetFromJsonAsync<IEnumerable<Champion>>("v1/Champions?name=" + substring+"&index=" + index + "&size=" + count);
}
public async Task<int> GetNbItems()
{
//HttpResponseMessage response =
//Console.WriteLine(response.Content.ToString());
//return int.Parse(response.Content.ToString());
//return await httpc.GetFromJsonAsync<int>("v1/Champions/count");
var response = await httpc.GetFromJsonAsync<ChampionCountResponse>("v1/Champions/count");
return response.Result;
}
public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByCharacteristic(string charName)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByClass(ChampionClass championClass)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByName(string substring)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsByRunePage(RunePage? runePage)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(Skill? skill)
{
throw new NotImplementedException();
}
public Task<int> GetNbItemsBySkill(string skill)
{
throw new NotImplementedException();
}
public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
{
HttpResponseMessage rep = await httpc.PutAsJsonAsync("v1/Champions?name=" + oldItem.Name, newItem.ToDTO());
if (rep.IsSuccessStatusCode) return newItem;
//else
return null;
}
}
}
}

@ -0,0 +1,27 @@
using Model;
namespace HttpClient
{
public partial class HttpClientManager : IDataManager
{
public System.Net.Http.HttpClient httpC { get; set; } = new System.Net.Http.HttpClient();
public HttpClientManager() {
ChampionsMgr = new ChampionManager(this, httpC);
httpC.BaseAddress = new Uri("https://localhost:7144/api/");
}
public ISkinsManager SkinsMgr => throw new NotImplementedException();
public IRunesManager RunesMgr => throw new NotImplementedException();
public IRunePagesManager RunePagesMgr => throw new NotImplementedException();
public IChampionsManager ChampionsMgr { get; set; }
}
}

@ -26,6 +26,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Api_UT", "Api_UT\Api_UT.csp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EF_UT", "EF_UT\EF_UT.csproj", "{74F469C3-A94A-4507-9DC7-7DBADCD18173}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpClient", "HttpClient\HttpClient.csproj", "{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{6570AF99-3E74-4CAA-AEB0-EEFE4F79780F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApplication", "ConsoleApplication\ConsoleApplication.csproj", "{53A195F7-FB7C-44E8-AB82-4D775C7D9477}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -64,6 +70,14 @@ Global
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74F469C3-A94A-4507-9DC7-7DBADCD18173}.Release|Any CPU.Build.0 = Release|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE2E40D5-1B4D-491C-B7E7-4E91B32DB93F}.Release|Any CPU.Build.0 = Release|Any CPU
{53A195F7-FB7C-44E8-AB82-4D775C7D9477}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53A195F7-FB7C-44E8-AB82-4D775C7D9477}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53A195F7-FB7C-44E8-AB82-4D775C7D9477}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53A195F7-FB7C-44E8-AB82-4D775C7D9477}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -72,6 +86,7 @@ Global
{B01D7EF2-2D64-409A-A29A-61FB7BB7A9DB} = {2C607793-B163-4731-A4D1-AFE8A7C4C170}
{20A1A7DC-1E93-4506-BD32-8597A5DADD7B} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
{74F469C3-A94A-4507-9DC7-7DBADCD18173} = {C76D0C23-1FFA-4963-93CD-E12BD643F030}
{53A195F7-FB7C-44E8-AB82-4D775C7D9477} = {6570AF99-3E74-4CAA-AEB0-EEFE4F79780F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {92F3083D-793F-4552-8A9A-0AD6534159C9}

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:LolApp.ViewModels"
xmlns:myviews="clr-namespace:LolApp.ContentViews"
xmlns:appvm="clr-namespace:LolApp.ViewModels"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="LolApp.AddChampionPage"
Title="AddChampionPage"
x:Name="root">
<Grid RowDefinitions="Auto,*, Auto" BackgroundColor="{StaticResource Black}">
<VerticalStackLayout>
<Label Text="Nouveau Champion" IsVisible="{Binding IsNew}"
Style="{StaticResource title}"/>
<Label Text="Modifier le Champion" IsVisible="{Binding IsNew, Converter={StaticResource invertedBoolConverter}}"
Style="{StaticResource title}"/>
<Grid><Line Stroke="{StaticResource Primary}"
X1="0" Y1="0" X2="200" Y2="0"
HorizontalOptions="Center"/>
</Grid>
</VerticalStackLayout>
<ScrollView Grid.Row="1">
<Grid ColumnDefinitions="*, 3*" RowDefinitions="Auto, Auto, Auto, 162, 162, Auto, Auto, Auto, Auto">
<Label Text="Nom :"
Style="{StaticResource labelForEntry}"/>
<Entry Grid.Column="1" Placeholder="Nom du champion" Text="{Binding Champion.Name}"
Style="{StaticResource defaultEntry}"
IsEnabled="{Binding IsNew}"/>
<Label Text="Icone :" Grid.Row="1" Style="{StaticResource labelForEntry}"/>
<ImageButton Grid.Row="1" Grid.Column="1" HeightRequest="42" WidthRequest="42"
Source="{Binding Champion.IconBase64, TargetNullValue='lol.png',
Converter={StaticResource base64ToImageSourceConverter}}"
BackgroundColor="{StaticResource Secondary}"
HorizontalOptions="Start"
Margin="6"
Command="{Binding PickIconCommand}"/>
<Label Text="Image :" Grid.Row="2" Style="{StaticResource labelForEntry}"/>
<Grid Grid.Row="2" Grid.Column="1" x:Name="largeImageGrid" Margin="0, 0, 12, 0">
<ImageButton WidthRequest="{Binding Width, Source={x:Reference largeImageGrid}}"
HeightRequest="150"
Source="{Binding Champion.LargeImageBase64, TargetNullValue='lollogo.jpg',
Converter={StaticResource base64ToImageSourceConverter}}"
BackgroundColor="{StaticResource Secondary}"
HorizontalOptions="Start"
Margin="6"
Command="{Binding PickLargeImageCommand}"/>
</Grid>
<Label Text="Bio :" Grid.Row="3"
Style="{StaticResource labelForEntry}"/>
<Editor Grid.Column="1" Grid.Row="3"
Text="{Binding Champion.Bio}" Style="{StaticResource defaultEditor}"/>
<Label Text="Classe :" Grid.Row="4"
Style="{StaticResource labelForEntry}"/>
<myviews:ChampionClassSelector Grid.Row="4" Grid.Column="1" MaximumWidthRequest="{OnPlatform WinUI=400}"
CheckedColor="{StaticResource Primary}"
UncheckedColor="{StaticResource Secondary}"
SelectedValue="{Binding Champion.ChampionClass, Mode=TwoWay}"/>
<Label Text="Caractéristiques :" Grid.Row="5" Grid.RowSpan="2"
Style="{StaticResource labelForEntry}" VerticalOptions="Start"/>
<Border Stroke="{StaticResource Secondary}" Grid.Row="5" Grid.Column="1" VerticalOptions="FillAndExpand"> <ListView ItemsSource="{Binding Champion.Characteristics}"
Margin="6" HeightRequest="100" HorizontalOptions="Fill" VerticalOptions="Fill"
BackgroundColor="{StaticResource Black}" SeparatorColor="{StaticResource Secondary}" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Command="{Binding Source={x:Reference root}, Path=BindingContext.RemoveCharacteristicCommand}"
CommandParameter="{Binding .}"
IsDestructive="True" Text="Delete"/>
</ViewCell.ContextActions>
<Border Margin="0,4" BackgroundColor="{StaticResource Secondary}">
<Border.StrokeShape>
<RoundRectangle CornerRadius="10, 10, 0, 10"/>
</Border.StrokeShape>
<Grid ColumnDefinitions="*, Auto">
<Label Text="{Binding Key}" TextColor="{StaticResource Black}"
HorizontalOptions="Start" VerticalOptions="Center" Margin="4, 0, 0, 0"/>
<Label Text="{Binding Value}" Grid.Column="1" TextColor="{StaticResource Black}"
HorizontalOptions="End" VerticalOptions="Center" Margin="0, 0, 4, 0"/>
</Grid>
</Border>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border>
<Grid Grid.Column="1" Grid.Row="6" ColumnDefinitions="*, 58, Auto">
<Entry Style="{StaticResource defaultEntry}" Placeholder="Caractéristique" Text="{Binding NewCharacteristicDescription}"/>
<Entry Style="{StaticResource defaultEntry}" Placeholder="Valeur" Grid.Column="1" Text="{Binding NewCharacteristicValue}" Keyboard="Numeric">
<Entry.Behaviors>
<toolkit:NumericValidationBehavior Flags="ValidateOnValueChanged"
MinimumValue="0"
MaximumValue="9999999"
MaximumDecimalPlaces="0"
InvalidStyle="{StaticResource InvalidEntryStyle}"
ValidStyle="{StaticResource defaultEntry}"/>
</Entry.Behaviors>
</Entry>
<Button Grid.Column="2" Margin="4,8" CornerRadius="22"
Text="{StaticResource plus}"
Command="{Binding AddCharacteristicCommand}"/>
</Grid>
<Label Style="{StaticResource labelForEntry}" Text="Compétences :" Grid.Row="7" VerticalOptions="Start"/>
<Grid Grid.Row="7" Grid.Column="1" ColumnDefinitions="*, Auto">
<ListView ItemsSource="{Binding Champion.Skills}" Margin="6"
HeightRequest="100" HorizontalOptions="Fill" VerticalOptions="Fill" HasUnevenRows="True"
BackgroundColor="{StaticResource Black}" SeparatorColor="{StaticResource Secondary}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid RowDefinitions="Auto, Auto, *">
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource Primary}"/>
</Style>
</Grid.Resources>
<Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" VerticalOptions="Center"/>
<Label Text="{Binding Type}" Grid.Row="1" VerticalOptions="Center" FontAttributes="Italic" FontSize="Micro"/>
<Label Text="{Binding Description}" FontSize="Micro" FontAttributes="Italic"
Grid.Row="2"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Grid.Column="1" Margin="4,8" CornerRadius="22"
Text="{StaticResource plus}" VerticalOptions="Start"
Command="{Binding AddSkillCommand}"/>
</Grid>
</Grid>
</ScrollView>
<HorizontalStackLayout Grid.Row="2" HorizontalOptions="Center" Spacing="40" Margin="0, 10, 0, 20">
<Button Text="Ajouter" Command="{Binding AddChampionCommand}" IsVisible="{Binding IsNew}"/>
<Button Text="Modifier" Command="{Binding EditChampionCommand}" IsVisible="{Binding IsNew, Converter={StaticResource invertedBoolConverter}}"/>
<Button Text="Annuler" Command="{Binding CancelCommand}"/>
</HorizontalStackLayout>
</Grid>
</ContentPage>

@ -0,0 +1,13 @@
using LolApp.ViewModels;
using ViewModels;
namespace LolApp;
public partial class AddChampionPage : ContentPage
{
public AddChampionPage(ChampionsMgrVM championsMgrVM, ChampionVM champion = null)
{
InitializeComponent();
BindingContext = new AddChampionPageVM(championsMgrVM, champion);
}
}

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="LolApp.AddOrEditSkinPage"
Title="AddOrEditSkinPage"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
<Grid RowDefinitions="Auto,*, Auto" BackgroundColor="{StaticResource Black}">
<VerticalStackLayout>
<Label Text="Nouveau Skin" IsVisible="{Binding IsNew}"
Style="{StaticResource title}"/>
<Label Text="Modifier le Skin" IsVisible="{Binding IsNew, Converter={StaticResource invertedBoolConverter}}"
Style="{StaticResource title}"/>
<Grid><Line Stroke="{StaticResource Primary}"
X1="0" Y1="0" X2="200" Y2="0"
HorizontalOptions="Center"/>
</Grid>
</VerticalStackLayout>
<ScrollView Grid.Row="1">
<Grid ColumnDefinitions="*, 3*" RowDefinitions="Auto, Auto, Auto, Auto, 162">
<Label Text="Nom :"
Style="{StaticResource labelForEntry}"/>
<Entry Grid.Column="1" Placeholder="Nom du skin" Text="{Binding Skin.Name}"
Style="{StaticResource defaultEntry}"
IsEnabled="{Binding IsNew}"/>
<Label Text="Icone :" Grid.Row="1" Style="{StaticResource labelForEntry}"/>
<ImageButton Grid.Row="1" Grid.Column="1" HeightRequest="42" WidthRequest="42"
Source="{Binding Skin.IconBase64, TargetNullValue='lol.png',
Converter={StaticResource base64ToImageSourceConverter}}"
BackgroundColor="{StaticResource Secondary}"
HorizontalOptions="Start"
Margin="6"
Command="{Binding PickIconCommand}"/>
<Label Text="Image :" Grid.Row="2" Style="{StaticResource labelForEntry}"/>
<Grid Grid.Row="2" Grid.Column="1" x:Name="largeImageGrid" Margin="0, 0, 12, 0">
<ImageButton WidthRequest="{Binding Width, Source={x:Reference largeImageGrid}}"
HeightRequest="150"
Source="{Binding Skin.LargeImageBase64, TargetNullValue='lollogo.jpg',
Converter={StaticResource base64ToImageSourceConverter}}"
BackgroundColor="{StaticResource Secondary}"
HorizontalOptions="Start"
Margin="6"
Command="{Binding PickLargeImageCommand}"/>
</Grid>
<Label Text="Prix :" Grid.Row="3"
Style="{StaticResource labelForEntry}"/>
<HorizontalStackLayout Grid.Column="1" Grid.Row="3" Margin="6">
<Image Source="rp.png" HeightRequest="16" WidthRequest="16"/>
<Entry Grid.Column="1" Placeholder="Nom du skin" Text="{Binding Skin.Price}"
Style="{StaticResource defaultEntry}" Margin="4, 0, 0, 0" HorizontalTextAlignment="Start">
<Entry.Behaviors>
<toolkit:NumericValidationBehavior Flags="ValidateOnValueChanged"
MinimumValue="0"
MaximumValue="9999999"
MaximumDecimalPlaces="0"
InvalidStyle="{StaticResource InvalidEntryStyle}"
ValidStyle="{StaticResource defaultEntry}"/>
</Entry.Behaviors>
</Entry>
</HorizontalStackLayout>
<Label Text="Description :" Grid.Row="4"
Style="{StaticResource labelForEntry}"/>
<Editor Grid.Column="1" Grid.Row="4"
Text="{Binding Skin.Description}" Style="{StaticResource defaultEditor}"/>
</Grid>
</ScrollView>
<HorizontalStackLayout Grid.Row="2" HorizontalOptions="Center" Spacing="40" Margin="0, 10, 0, 20">
<Button Text="Ajouter" Command="{Binding AddSkinCommand}" IsVisible="{Binding IsNew}"/>
<Button Text="Modifier" Command="{Binding EditSkinCommand}" IsVisible="{Binding IsNew, Converter={StaticResource invertedBoolConverter}}"/>
<Button Text="Annuler" Command="{Binding CancelCommand}"/>
</HorizontalStackLayout>
</Grid>
</ContentPage>

@ -0,0 +1,24 @@
using LolApp.ViewModels;
using ViewModels;
namespace LolApp;
public partial class AddOrEditSkinPage : ContentPage
{
AddOrEditSkinPage()
{
InitializeComponent();
}
public AddOrEditSkinPage(SkinsMgrVM skinsMgrVM, SkinVM skin)
:this()
{
BindingContext = new AddOrEditSkinPageVM(skinsMgrVM, skin);
}
public AddOrEditSkinPage(SkinsMgrVM skinsMgrVM, ChampionVM champion)
:this()
{
BindingContext = new AddOrEditSkinPageVM(skinsMgrVM, champion);
}
}

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="LolApp.AddSkill"
xmlns:appvm="clr-namespace:LolApp.ViewModels"
Title="AddSkill">
<Grid RowDefinitions="Auto,*, Auto" BackgroundColor="{StaticResource Gray900}">
<VerticalStackLayout>
<Label Text="Nouvelle Compétence"
Style="{StaticResource title}"/>
<Grid>
<Line Stroke="{StaticResource Primary}"
X1="0" Y1="0" X2="200" Y2="0"
HorizontalOptions="Center"/>
</Grid>
</VerticalStackLayout>
<ScrollView Grid.Row="1">
<Grid ColumnDefinitions="*, 3*" RowDefinitions="Auto, Auto, *">
<Label Text="Nom :" Style="{StaticResource labelForEntry}"/>
<Entry Text="{Binding Name}" Style="{StaticResource defaultEntry}"
Grid.Column="1"/>
<Label Text="Type :" Style="{StaticResource labelForEntry}" Grid.Row="1"/>
<Picker ItemsSource="{Binding AllSkills}" SelectedItem="{Binding SkillType}"
Grid.Row="1" Grid.Column="1"
Style="{StaticResource defaultPicker}"/>
<Label Text="Description :" Style="{StaticResource labelForEntry}" Grid.Row="2"/>
<Editor Grid.Row="2" Grid.Column="1" Text="{Binding Description}"
Style="{StaticResource defaultEditor}"/>
</Grid>
</ScrollView>
<HorizontalStackLayout Grid.Row="2" HorizontalOptions="Center" Spacing="40" Margin="0, 10, 0, 20">
<Button Text="Ajouter" Command="{Binding AddSkillToChampionCommand}"/>
<Button Text="Annuler" Command="{Binding CancelCommand}"/>
</HorizontalStackLayout>
</Grid>
</ContentPage>

@ -0,0 +1,13 @@
using LolApp.ViewModels;
using ViewModels;
namespace LolApp;
public partial class AddSkill : ContentPage
{
public AddSkill(EditableChampionVM champion)
{
InitializeComponent();
BindingContext = new AddSkillVM(champion);
}
}

@ -0,0 +1,18 @@
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:LolApp"
x:Class="LolApp.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/FontAwesomeGlyphs.xaml" x:Name="Colors" />
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
<ResourceDictionary Source="Resources/Styles/MyStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

@ -0,0 +1,12 @@
namespace LolApp;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
}

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="LolApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:LolApp"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage"
Icon="{OnPlatform 'lol.png'}" />
<ShellContent
Title="Champions"
ContentTemplate="{DataTemplate local:ChampionsPage}"
Route="Championspage"
Icon="{OnPlatform 'sword.png'}" />
</TabBar>
</Shell>

@ -0,0 +1,10 @@
namespace LolApp;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="LolApp.ChampionPage"
Title="ChampionPage"
x:Name="root"
BackgroundColor="Black">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Modifier" Command="{Binding AppVM.NavigateToEditChampionPageCommand, Source={x:Reference root}}"
CommandParameter="{Binding}"/>
</ContentPage.ToolbarItems>
<ScrollView>
<VerticalStackLayout>
<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
MaximumHeightRequest="{OnPlatform WinUI=300}"
HeightRequest="{Binding Width,
Source={RelativeSource AncestorType={x:Type ContentPage}},
Converter={StaticResource imageRatioConverter},
ConverterParameter={StaticResource imageRatio}}">
<Image Source="{Binding Image, Converter={StaticResource base64ToImageSourceConverter}}"
Aspect="AspectFit"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
MaximumHeightRequest="{OnPlatform WinUI=300}"/>
</AbsoluteLayout>
<Grid Padding="10" BackgroundColor="{StaticResource Black}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" FontAttributes="Bold" TextColor="{StaticResource Primary}"
FontSize="Title"/>
<VerticalStackLayout Grid.Column="1" HorizontalOptions="Center">
<Image Source="{Binding Class, Converter={StaticResource championClassToIconConverter}}"
HeightRequest="26" WidthRequest="26" x:Name="imgClass" PropertyChanged="imgClass_PropertyChanged">
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="{StaticResource Primary}"
x:Name="tintColor"/>
</Image.Behaviors>
</Image>
<Label Text="{Binding Class}" TextColor="{StaticResource Primary}"
FontSize="Micro"/>
</VerticalStackLayout>
</Grid>
<ScrollView VerticalScrollBarVisibility="Always" BackgroundColor="Black" >
<Label Text="{Binding Bio}" TextColor="{StaticResource Primary}" Padding="10" FontAttributes="Italic"/>
</ScrollView>
<Label Padding="10" Text="Caractéristiques" FontSize="Title" TextColor="{StaticResource Primary}"
BackgroundColor="Black"/>
<Grid MaximumHeightRequest="240">
<Grid.Resources>
<x:Double x:Key="gridHeight">120</x:Double>
<x:Int32 x:Key="nbCellsPerLine">3</x:Int32>
</Grid.Resources>
<Grid.HeightRequest>
<MultiBinding Converter="{StaticResource multiMathExpressionConverter}"
ConverterParameter="ceiling(x1/x2)*x0">
<Binding Source="{StaticResource gridHeight}"/>
<Binding Path="Characteristics.Count"/>
<Binding Source="{StaticResource nbCellsPerLine}"/>
</MultiBinding>
</Grid.HeightRequest>
<CollectionView ItemsSource="{Binding Characteristics}"
ItemsLayout="VerticalGrid, 3"
VerticalScrollBarVisibility="Always">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10" HeightRequest="120">
<Border Stroke="{StaticResource PrimaryBrush}" StrokeThickness="2" BackgroundColor="{StaticResource Black}">
<Grid RowDefinitions="4*,3*">
<Label Text="{Binding Key}" HorizontalOptions="Center" TextColor="{StaticResource Primary}"
FontSize="Small" FontAttributes="Bold" VerticalOptions="End" HorizontalTextAlignment="Center"
Margin="0, 0, 0, 5"/>
<Label Grid.Row="1" Text="{Binding Value}" HorizontalOptions="Center" TextColor="{StaticResource Primary}"
VerticalOptions="Start" HorizontalTextAlignment="Center"
FontSize="Small"/>
</Grid>
</Border>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
<Label Padding="10" Text="Compétences" FontSize="Title" TextColor="{StaticResource Primary}"
BackgroundColor="Black"/>
<ListView ItemsSource="{Binding Skills}" Margin="10"
BackgroundColor="Black" HasUnevenRows="True" VerticalScrollBarVisibility="Always"
MaximumHeightRequest="400">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource Primary}"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" VerticalOptions="Center"/>
<Label Text="{Binding Type}" Grid.Column="1" VerticalOptions="Center" FontAttributes="Italic" FontSize="Micro"/>
<Label Text="{Binding Description}" FontSize="Micro" FontAttributes="Italic"
Grid.ColumnSpan="2" Grid.Row="1"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid ColumnDefinitions="*, Auto">
<Label Padding="10" Text="Skins" FontSize="Title" TextColor="{StaticResource Primary}"
BackgroundColor="Black"/>
<Button Grid.Column="1" Text="{StaticResource plus}" CornerRadius="22" BackgroundColor="{StaticResource Primary}"
TextColor="{StaticResource Black}" FontSize="Header"
Command="{Binding AppVM.NavigateToAddNewSkinPageCommand, Source={x:Reference root}}"
CommandParameter="{Binding}"
VerticalOptions="Center" HorizontalOptions="Center"
Margin="6"/>
</Grid>
<ListView BindingContext="{Binding AppVM, Source={x:Reference root}}"
ItemsSource="{Binding SkinsMgrVM.Skins}" HasUnevenRows="True"
BackgroundColor="{StaticResource Black}"
x:Name="listSkins">
<ListView.Behaviors>
<toolkit:EventToCommandBehavior
EventName="ItemSelected"
Command="{Binding NavigateToSkinDetailsPageCommand}"
EventArgsConverter="{StaticResource SelectedItemEventArgsConverter}"
/>
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem IsDestructive="True"
Text="Supprimer"
Command="{Binding BindingContext.SkinsMgrVM.DeleteSkinCommand, Source={x:Reference listSkins}}"
CommandParameter="{Binding .}"/>
<MenuItem Text="Modifier"
Command="{Binding Source={x:Reference listSkins}, Path=BindingContext.NavigateToEditSkinPageCommand}"
CommandParameter="{Binding .}"/>
</ViewCell.ContextActions>
<Border Stroke="{StaticResource Primary}" Padding="8,4" HeightRequest="60" Margin="4"
StrokeThickness="3" BackgroundColor="{StaticResource Black}">
<Border.StrokeShape>
<RoundRectangle CornerRadius="0, 10, 10, 10"/>
</Border.StrokeShape>
<HorizontalStackLayout VerticalOptions="Center">
<Image Source="{Binding Icon, Converter={StaticResource base64ToImageSourceConverter}}"
HeightRequest="46" WidthRequest="46"/>
<Label Text="{Binding Name}" TextColor="{StaticResource Primary}" FontSize="Small"
VerticalOptions="Center" Margin="10,4"/>
</HorizontalStackLayout>
</Border>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ScrollView>
</ContentPage>

@ -0,0 +1,31 @@
using CommunityToolkit.Maui.Behaviors;
using LolApp.ViewModels;
using ViewModels;
namespace LolApp;
public partial class ChampionPage : ContentPage
{
public ApplicationVM AppVM { get; set; }
public ChampionVM Champion { get; }
public ChampionPage(ChampionVM cvm, ApplicationVM appVM)
{
AppVM = appVM;
BindingContext = Champion = cvm;
InitializeComponent();
}
void imgClass_PropertyChanged(System.Object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
Image img = sender as Image;
if(e.PropertyName == "Source" && img != null && img.Behaviors.Any(b => b is IconTintColorBehavior))
{
var beh = (img.Behaviors.First(b => b is IconTintColorBehavior) as IconTintColorBehavior);
var color = beh.TintColor;
img.Behaviors.Remove(beh);
img.Behaviors.Add(new IconTintColorBehavior() { TintColor = color});
}
}
}

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:myviews="clr-namespace:LolApp.ContentViews"
xmlns:vm="clr-namespace:ViewModels;assembly=ViewModels"
xmlns:appvm="clr-namespace:LolApp.ViewModels"
x:Class="LolApp.ChampionsPage"
Title="Champions"
x:Name="root">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Ajouter" Command="{Binding AppVM.NavigateToAddNewChampionPageCommand}" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
<ControlTemplate x:Key="searchByStringControl">
<Grid Margin="20,4" HeightRequest="{OnPlatform 30, Android=40}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Entry Placeholder="{TemplateBinding PlaceHolder}"
Text="{TemplateBinding Text, Mode=TwoWay}"/>
<Button Text="{StaticResource magnifying-glass}"
FontFamily="FASolid"
Grid.Column="1" Margin="4, 0, 0, 0"
Command="{TemplateBinding Command}"
CommandParameter="{TemplateBinding CommandParameter}"/>
</Grid>
</ControlTemplate>
</ContentPage.Resources>
<ContentPage.Behaviors>
<toolkit:EventToCommandBehavior
EventName = "Loaded"
Command="{Binding AppVM.ChampionsMgrVM.LoadChampionsCommand}"/>
</ContentPage.Behaviors>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<toolkit:Expander Grid.Row="1">
<toolkit:Expander.Header>
<HorizontalStackLayout>
<Label Text="Chercher par "
HorizontalOptions="Center"/>
<Label Text="nom" IsVisible="{Binding VM.SearchedName, Converter={StaticResource isStringNotNullOrWhiteSpaceConverter}}"/>
<Label Text="compétence" IsVisible="{Binding VM.SearchedSkill, Converter={StaticResource isStringNotNullOrWhiteSpaceConverter}}"/>
<Label Text=" "/>
<Label Text="{Binding IsExpanded,
Source={RelativeSource AncestorType={x:Type toolkit:Expander}},
Converter={StaticResource isExpandedToCaretConverter}}"
FontFamily="FASolid"
VerticalOptions="Center"/>
</HorizontalStackLayout>
</toolkit:Expander.Header>
<VerticalStackLayout HorizontalOptions="Fill" BackgroundColor="WhiteSmoke">
<myviews:SearchByStringView ControlTemplate="{StaticResource searchByStringControl}"
PlaceHolder="Entrez un nom"
Text="{Binding VM.SearchedName, Mode=TwoWay}"
Command="{Binding AppVM.ChampionsMgrVM.LoadChampionsByNameCommand}"
CommandParameter="{Binding VM.SearchedName}"/>
<myviews:SearchByStringView ControlTemplate="{StaticResource searchByStringControl}"
PlaceHolder="Entrez une compétence"
Text="{Binding VM.SearchedSkill, Mode=TwoWay}"
Command="{Binding AppVM.ChampionsMgrVM.LoadChampionsBySkillCommand}"
CommandParameter="{Binding VM.SearchedSkill}"/>
<myviews:SearchByStringView ControlTemplate="{StaticResource searchByStringControl}"
PlaceHolder="Entrez une caractéristique"
Text="{Binding VM.SearchedCharacteristic, Mode=TwoWay}"
Command="{Binding AppVM.ChampionsMgrVM.LoadChampionsByCharacteristicCommand}"
CommandParameter="{Binding VM.SearchedCharacteristic}"/>
<Label Text="Filtrer par classe :" Margin="20, 4, 0, 0"
FontSize="Micro"/>
<CollectionView ItemsSource="{x:Static appvm:ChampionClassVM.Classes}" ItemsLayout="VerticalGrid, 3"
SelectionMode="Single" HeightRequest="110" x:Name="classesView"
SelectionChangedCommand="{Binding AppVM.ChampionsMgrVM.LoadChampionsByClassCommand}"
SelectionChangedCommandParameter="{Binding VM.SelectedItem, Source={RelativeSource Self}}"
SelectedItem="{Binding VM.SelectedClass, Source={x:Reference root}, Mode=TwoWay}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid HorizontalOptions="Center" RowDefinitions="*, *" WidthRequest="100" Padding="10, 10, 10, 0"
BackgroundColor="{Binding IsSelected, Converter={StaticResource isSelectedToColorConverter}}">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference root}, Path=BindingContext.VM.SelectedChampionClassChangedCommand}"
CommandParameter="{Binding}" />
</Grid.GestureRecognizers>
<Image Source="{Binding Model, Converter={StaticResource championClassToIconConverter}}" HeightRequest="26" WidthRequest="26"
/>
<Label Text="{Binding Model}" TextColor="{StaticResource Black}"
HorizontalOptions="Center" Grid.Row="1"
FontSize="Micro">
</Label>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</toolkit:Expander>
<ListView Grid.Row="2" CachingStrategy="RecycleElementAndDataTemplate"
ItemsSource="{Binding AppVM.ChampionsMgrVM.Champions}"
RowHeight="50"
SelectedItem="{Binding AppVM.ChampionsMgrVM.SelectedChampion, Mode=TwoWay}">
<ListView.Behaviors>
<toolkit:EventToCommandBehavior
EventName="ItemSelected"
Command="{Binding AppVM.NavigateToChampionDetailsPageCommand}"
EventArgsConverter="{StaticResource SelectedItemEventArgsConverter}"
/>
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Command="{Binding Source={x:Reference root}, Path=BindingContext.AppVM.ChampionsMgrVM.DeleteChampionCommand}"
CommandParameter="{Binding .}"
IsDestructive="True" Text="Supprimer"/>
<MenuItem Command="{Binding Source={x:Reference root}, Path=BindingContext.AppVM.NavigateToEditChampionPageCommand}"
CommandParameter="{Binding .}"
IsDestructive="False" Text="Modifier"/>
</ViewCell.ContextActions>
<Grid Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Source="{Binding Icon, Converter={StaticResource base64ToImageSourceConverter}}"
HeightRequest="40"
WidthRequest="40"
Grid.RowSpan="2"
VerticalOptions="Center"
Margin="0, 0, 10, 0"/>
<Label Text="{Binding Name}" Grid.Column="1"
FontAttributes="Bold"
FontSize="{OnPlatform Header, WinUI=Small}"
VerticalOptions="Center"/>
<Label Text="{Binding Class}" Grid.Row="1" Grid.Column="1"
FontAttributes="Italic"
FontSize="Caption"
VerticalOptions="Center"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Row="3" HorizontalOptions="Center" HeightRequest="45"
IsVisible="{Binding AppVM.ChampionsMgrVM.NbChampions, Converter={StaticResource intToBoolConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Style="{StaticResource iconButton}"
Command="{Binding AppVM.ChampionsMgrVM.PreviousPageCommand}">
<Button.ImageSource>
<FontImageSource Glyph="{StaticResource angle-left}"
FontFamily="FASolid"
Size="Title"/>
</Button.ImageSource>
</Button>
<StackLayout Orientation="Horizontal" Grid.Column="1"
HorizontalOptions="Center" VerticalOptions="Center">
<StackLayout.Resources>
<Style BasedOn="{StaticResource defaultLabel}" TargetType="Label">
<Setter Property="Margin" Value="2"/>
</Style>
</StackLayout.Resources>
<Label Text="{Binding AppVM.ChampionsMgrVM.Index, Converter={StaticResource plusOneConverter}}" HorizontalOptions="End"/>
<Label Text="/"/>
<Label Text="{Binding AppVM.ChampionsMgrVM.NbPages}" HorizontalOptions="Start"/>
</StackLayout>
<Button Grid.Column="2" Style="{StaticResource iconButton}"
Command="{Binding AppVM.ChampionsMgrVM.NextPageCommand}">
<Button.ImageSource>
<FontImageSource Glyph="{StaticResource angle-right}" FontFamily="FASolid"
Size="Title"/>
</Button.ImageSource>
</Button>
</Grid>
</Grid>
</ContentPage>

@ -0,0 +1,17 @@
using LolApp.ViewModels;
using ViewModels;
namespace LolApp;
public partial class ChampionsPage : ContentPage
{
public ApplicationVM AppVM { get; }
public ChampionsPageVM VM { get; }
public ChampionsPage(ApplicationVM appVM)
{
InitializeComponent();
AppVM = appVM;
VM = new ChampionsPageVM(AppVM.ChampionsMgrVM);
BindingContext = this;
}
}

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:model="clr-namespace:Model;assembly=Model"
x:Class="LolApp.ContentViews.ChampionClassSelector"
x:Name="root">
<ContentView.Resources>
<model:ChampionClass x:Key="assassin">Assassin</model:ChampionClass>
<model:ChampionClass x:Key="fighter">Fighter</model:ChampionClass>
<model:ChampionClass x:Key="mage">Mage</model:ChampionClass>
<model:ChampionClass x:Key="marksman">Marksman</model:ChampionClass>
<model:ChampionClass x:Key="support">Support</model:ChampionClass>
<model:ChampionClass x:Key="tank">Tank</model:ChampionClass>
<ControlTemplate x:Key="RadioButtonTemplate">
<Border Stroke="{StaticResource Transparent}"
BackgroundColor="{StaticResource Transparent}"
HorizontalOptions="Fill"
VerticalOptions="Fill"
Padding="0">
<Border.StrokeShape>
<RoundRectangle CornerRadius="40, 40, 0, 40"/>
</Border.StrokeShape>
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="{Binding CheckedColor, Source={x:Reference root}}" />
<Setter Property="Stroke"
Value="{Binding CheckedColor, Source={x:Reference root}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="{Binding UncheckedColor, Source={x:Reference root}}" />
<Setter Property="Stroke"
Value="{Binding UncheckedColor, Source={x:Reference root}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid>
<ContentPresenter VerticalOptions="Center" HorizontalOptions="Center" />
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="RadioButton">
<Setter Property="ControlTemplate"
Value="{StaticResource RadioButtonTemplate}" />
</Style>
</ContentView.Resources>
<Grid ColumnDefinitions="*, *, *" RowDefinitions="*, *"
Margin="6" ColumnSpacing="6" RowSpacing="6"
RadioButtonGroup.GroupName="championClasses"
RadioButtonGroup.SelectedValue="{Binding SelectedValue, Source={x:Reference root}, Mode=TwoWay}">
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="{OnPlatform Micro, WinUI=12}"/>
</Style>
</Grid.Resources>
<RadioButton Value="{Binding Source={StaticResource assassin}}">
<RadioButton.Content>
<VerticalStackLayout>
<Image Source="{Binding Source={StaticResource assassin}, Converter={StaticResource championClassToIconConverter}}"
WidthRequest="26" HeightRequest="26" HorizontalOptions="Center"/>
<Label Text="Assassin" HorizontalOptions="Center"/>
</VerticalStackLayout>
</RadioButton.Content>
</RadioButton>
<RadioButton Grid.Column="1"
Value="{Binding Source={StaticResource fighter}}">
<RadioButton.Content>
<VerticalStackLayout>
<Image Source="{Binding Source={StaticResource fighter}, Converter={StaticResource championClassToIconConverter}}"
WidthRequest="26" HeightRequest="26" HorizontalOptions="Center"/>
<Label Text="Fighter" HorizontalOptions="Center"/>
</VerticalStackLayout>
</RadioButton.Content>
</RadioButton>
<RadioButton Grid.Column="2"
Value="{Binding Source={StaticResource mage}}">
<RadioButton.Content>
<VerticalStackLayout>
<Image Source="{Binding Source={StaticResource mage}, Converter={StaticResource championClassToIconConverter}}"
WidthRequest="26" HeightRequest="26" HorizontalOptions="Center"/>
<Label Text="Mage" HorizontalOptions="Center"/>
</VerticalStackLayout>
</RadioButton.Content>
</RadioButton>
<RadioButton Grid.Row="1" Grid.Column="0"
Value="{Binding Source={StaticResource marksman}}">
<RadioButton.Content>
<VerticalStackLayout>
<Image Source="{Binding Source={StaticResource marksman}, Converter={StaticResource championClassToIconConverter}}"
WidthRequest="26" HeightRequest="26" HorizontalOptions="Center"/>
<Label Text="Marksman" HorizontalOptions="Center"/>
</VerticalStackLayout>
</RadioButton.Content>
</RadioButton>
<RadioButton Grid.Row="1" Grid.Column="1"
Value="{Binding Source={StaticResource support}}">
<RadioButton.Content>
<VerticalStackLayout>
<Image Source="{Binding Source={StaticResource support}, Converter={StaticResource championClassToIconConverter}}"
WidthRequest="26" HeightRequest="26" HorizontalOptions="Center"/>
<Label Text="Support" HorizontalOptions="Center"/>
</VerticalStackLayout>
</RadioButton.Content>
</RadioButton>
<RadioButton Grid.Row="1" Grid.Column="2"
Value="{Binding Source={StaticResource tank}}">
<RadioButton.Content>
<VerticalStackLayout>
<Image Source="{Binding Source={StaticResource tank}, Converter={StaticResource championClassToIconConverter}}"
WidthRequest="26" HeightRequest="26" HorizontalOptions="Center"/>
<Label Text="Tank" HorizontalOptions="Center"/>
</VerticalStackLayout>
</RadioButton.Content>
</RadioButton>
</Grid>
</ContentView>

@ -0,0 +1,34 @@
using Model;
namespace LolApp.ContentViews;
public partial class ChampionClassSelector : ContentView
{
public ChampionClassSelector()
{
InitializeComponent();
}
public static readonly BindableProperty SelectedValueProperty = BindableProperty.Create(nameof(SelectedValue), typeof(ChampionClass), typeof(ChampionClassSelector), ChampionClass.Unknown, BindingMode.TwoWay);
public ChampionClass SelectedValue
{
get => (ChampionClass)GetValue(SelectedValueProperty);
set => SetValue(SelectedValueProperty, value);
}
public static readonly BindableProperty CheckedColorProperty = BindableProperty.Create(nameof(CheckedColor), typeof(Color), typeof(ChampionClassSelector), Colors.DarkSalmon);
public Color CheckedColor
{
get => (Color)GetValue(CheckedColorProperty);
set => SetValue(CheckedColorProperty, value);
}
public static readonly BindableProperty UncheckedColorProperty = BindableProperty.Create(nameof(UncheckedColor), typeof(Color), typeof(ChampionClassSelector), Colors.DarkSalmon);
public Color UncheckedColor
{
get => (Color)GetValue(UncheckedColorProperty);
set => SetValue(UncheckedColorProperty, value);
}
}

@ -0,0 +1,38 @@
using System.Windows.Input;
namespace LolApp.ContentViews;
public class SearchByStringView : ContentView
{
public static readonly BindableProperty PlaceHolderProperty = BindableProperty.Create(nameof(PlaceHolder), typeof(string), typeof(SearchByStringView), string.Empty);
public string PlaceHolder
{
get => (string)GetValue(PlaceHolderProperty);
set => SetValue(PlaceHolderProperty, value);
}
public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(SearchByStringView), string.Empty);
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(SearchByStringView), null);
public ICommand Command
{
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(nameof(CommandParameter), typeof(object), typeof(SearchByStringView), null);
public object CommandParameter
{
get => GetValue(CommandParameterProperty);
set => SetValue(CommandParameterProperty, value);
}
}

@ -0,0 +1,99 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>LolApp</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Display name -->
<ApplicationTitle>LolApp</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>fr.uca.iut.lolapp</ApplicationId>
<ApplicationIdGuid>d3cd18a9-c614-4933-bd36-3008e72004d5</ApplicationIdGuid>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
<ProjectGuid>{0C898A04-092A-49AA-BE65-8AE818A2AF50}</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
<CodesignProvision>appleIUT_TP2022</CodesignProvision>
<CodesignKey>iPhone Developer: Cedric BOUHOURS (M2E3ZQNZ3K)</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-maccatalyst|AnyCPU'">
<CreatePackage>false</CreatePackage>
<CodesignKey>Developer ID Application</CodesignKey>
<PackageSigningKey>3rd Party Mac Developer Installer</PackageSigningKey>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.22621.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiFont Include="Resources\Fonts\*" />
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
<MauiIcon Include="Resources\AppIcon\appicon.png" />
</ItemGroup>
<ItemGroup>
<None Remove="Resources\Images\fighter.svg" />
<None Remove="Resources\Images\lollogo.jpg" />
<None Remove="Resources\Images\sword.png" />
<None Remove="Resources\Images\lol.png" />
<None Remove="Resources\Fonts\Font Awesome 6 Free-Solid-900.otf" />
<None Remove="Resources\Images\support.svg" />
<None Remove="Resources\Images\tank.svg" />
<None Remove="Resources\Images\marksman.svg" />
<None Remove="Resources\Images\assassin.svg" />
<None Remove="Resources\Images\mage.svg" />
<None Remove="Resources\AppIcon\appicon.png" />
<None Remove="Resources\Splash\tank.svg" />
<None Remove="Resources\Splash\splash.png" />
<None Remove="Resources\Images\rp.png" />
</ItemGroup>
<ItemGroup>
<MauiImage Include="Resources\Images\lollogo.jpg" />
<MauiImage Include="Resources\Images\sword.png" />
<MauiImage Include="Resources\Images\lol.png" />
<MauiImage Include="Resources\Images\tank.svg" />
<MauiImage Include="Resources\Images\support.svg" />
<MauiImage Include="Resources\Images\marksman.svg" />
<MauiImage Include="Resources\Images\mage.svg" />
<MauiImage Include="Resources\Images\fighter.svg" />
<MauiImage Include="Resources\Images\assassin.svg" />
<MauiImage Include="Resources\Images\rp.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
<ProjectReference Include="..\StubLib\StubLib.csproj" />
<ProjectReference Include="..\ViewModels\ViewModels.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="5.0.0" />
<PackageReference Include="CommunityToolkit.Maui.Markup" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
<PackageReference Include="Microsoft.Maui.Graphics.Skia" Version="7.0.59" />
</ItemGroup>
<ItemGroup>
<MauiSplashScreen Include="Resources\Splash\splash.png" />
</ItemGroup>
</Project>

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="LolApp.MainPage">
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Image
Source="lollogo.jpg"
SemanticProperties.Description="Cute dot net bot waving hi to you!"
HeightRequest="200"
HorizontalOptions="Center" />
<Label
Text="League of Legends Data"
SemanticProperties.HeadingLevel="Level1"
FontSize="32"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"/>
<Label
Text="Find information about champions, skins and runes"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I"
FontSize="18"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>

@ -0,0 +1,11 @@
namespace LolApp;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}

@ -0,0 +1,39 @@
using CommunityToolkit.Maui;
using LolApp.ViewModels;
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using Model;
using StubLib;
using ViewModels;
namespace LolApp;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
fonts.AddFont("Font Awesome 6 Free-Solid-900.otf", "FASolid");
});
builder.Services.AddSingleton<IDataManager, StubData>()
.AddSingleton<ChampionsMgrVM>()
.AddSingleton<SkinsMgrVM>()
.AddSingleton<ApplicationVM>()
.AddSingleton<ChampionsPage>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="33" android:targetSdkVersion="33" />
</manifest>

@ -0,0 +1,11 @@
using Android.App;
using Android.Content.PM;
using Android.OS;
namespace LolApp;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}

@ -0,0 +1,16 @@
using Android.App;
using Android.Runtime;
namespace LolApp;
[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
</resources>

@ -0,0 +1,10 @@
using Foundation;
namespace LolApp;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
<key>NSCameraUsageDescription</key>
<string>New Entry</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>New Entry</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>New Entry</string>
</dict>
</plist>

@ -0,0 +1,16 @@
using ObjCRuntime;
using UIKit;
namespace LolApp;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}

@ -0,0 +1,17 @@
using System;
using Microsoft.Maui;
using Microsoft.Maui.Hosting;
namespace LolApp;
class Program : MauiApplication
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
static void Main(string[] args)
{
var app = new Program();
app.Run(args);
}
}

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="maui-application-id-placeholder" version="0.0.0" api-version="7" xmlns="http://tizen.org/ns/packages">
<profile name="common" />
<ui-application appid="maui-application-id-placeholder" exec="LolApp.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
<label>maui-application-title-placeholder</label>
<icon>maui-appicon-placeholder</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
</ui-application>
<shortcut-list />
<privileges>
<privilege>http://tizen.org/privilege/internet</privilege>
</privileges>
<dependencies />
<provides-appdefined-privileges />
</manifest>

@ -0,0 +1,9 @@
<maui:MauiWinUIApplication
x:Class="LolApp.WinUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maui="using:Microsoft.Maui"
xmlns:local="using:LolApp.WinUI">
</maui:MauiWinUIApplication>

@ -0,0 +1,25 @@
using Microsoft.UI.Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace LolApp.WinUI;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : MauiWinUIApplication
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
<mp:PhoneIdentity PhoneProductId="B9226665-2A86-4F1D-BB62-983AD09442FD" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>$placeholder$</DisplayName>
<PublisherDisplayName>User Name</PublisherDisplayName>
<Logo>$placeholder$.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="$placeholder$"
Description="$placeholder$"
Square150x150Logo="$placeholder$.png"
Square44x44Logo="$placeholder$.png"
BackgroundColor="transparent">
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png" Square310x310Logo="$placeholder$.png" />
<uap:SplashScreen Image="$placeholder$.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="LolApp.WinUI.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- The combination of below two tags have the following effect:
1) Per-Monitor for >= Windows 10 Anniversary Update
2) System < Windows 10 Anniversary Update
-->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>

@ -0,0 +1,10 @@
using Foundation;
namespace LolApp;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
<key>NSCameraUsageDescription</key>
<string>New Entry</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Pour accéder aux images...</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Pour accéder aux images...</string>
</dict>
</plist>

@ -0,0 +1,16 @@
using ObjCRuntime;
using UIKit;
namespace LolApp;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}

@ -0,0 +1,8 @@
{
"profiles": {
"Windows Machine": {
"commandName": "MsixPackage",
"nativeDebugging": false
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save