Merge pull request 'Base de la persistance des données' (#39) from feature/36-persistance into dev
continuous-integration/drone/push Build is passing Details

Reviewed-on: #39
pull/44/head
Alexandre AGOSTINHO 2 years ago
commit 7a15ac8b49

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

@ -1,4 +1,5 @@
using Model;
using DataPersistence;
using System;
using System.Collections.Generic;
using System.Linq;
@ -15,7 +16,7 @@ namespace ConsoleApp.Menu
public MainMenu(DataManager dataMgr)
: base("Main menu",
new Selector<IMenu>(
new SearcherRecipe(dataMgr.AllRecipes), "Recipe search"),
new SearcherRecipe(new RecipeCollection("search", dataMgr.Data[nameof(Recipe)].Cast<Recipe>().ToArray())), "Recipe search"),
new Selector<IMenu>(
new ConnectionMenu(), "Connection"))
{ }

@ -1,5 +1,6 @@
using ConsoleApp.Menu;
using Model;
using DataPersistence;
using System;
using System.Collections.Generic;
using System.Linq;

@ -2,23 +2,34 @@
using ConsoleApp;
using ConsoleApp.Menu;
using DataPersistence;
using Model;
using System.Linq;
using System.Text;
Console.WriteLine("Hello, World!\n\n");
// TESTS:
DataManager dataMgr = new DataManager(new Stubs());
//DataManager dataMgr = new DataManager(new DataContractXML(xmlFolderPath: "../../../../DataPersistence/data"));
//DataManager dataMgr = new DataManager(new DataContractJSON());
//dataMgr.Serializer = new DataContractXML(xmlFolderPath: "../../../../DataPersistence/data");
dataMgr.Serializer = new DataContractJSON();
List<RecipeCollection> recipeCollections = Stub.LoadRecipeCollection();
RecipeCollection? allRecipe = recipeCollections.Find(x => x.Description.Equals("All"));
if (allRecipe == null)
throw new ArgumentException("Load AllRecipe in stub: can't find 'All'.");
// /!\ here is an absolute path I put for testing purpose. It will only work on my computer so don't forget to change it whene you test.
//dataMgr.Export(rc[2], "C:\\Users\\alex6\\Downloads\\recipe2.json");
//dataMgr.Import<Recipe>("C:\\Users\\alex6\\Downloads\\recipe2.json");
DataManager dataMgr = new DataManager(allRecipe);
RecipeCollection rc = new RecipeCollection("All recipes", dataMgr.Data[nameof(Recipe)].Cast<Recipe>().ToArray());
dataMgr.Save();
MenuManager menuMgr = new MenuManager(dataMgr);
menuMgr.Loop();
// press any key to quit
//Console.ReadKey();

@ -1,99 +0,0 @@
using Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp
{
internal struct Stub
{
public static List<Recipe> LoadRecipes()
{
List<Recipe> stub = new List<Recipe>();
stub.AddRange(new[]
{
new Recipe(),
new Recipe(
title: "Cookies"),
new Recipe(
title: "Cookies", id: 23),
new Recipe(
title: "Cookies au chocolat", id: null),
new Recipe(
title: "", id: null),
new Recipe(
title: "", id: 24),
new Recipe(
title: "Cookies", id: 24,
preparationSteps: new[]{
new PreparationStep(1)
}),
new Recipe(
title: "Cookies", id: 26,
preparationSteps: new[]{
new PreparationStep(1),
new PreparationStep(2, "Faire cuire.")
}),
new Recipe(
title: "Gateau à la crème",
preparationSteps: new[]{
new PreparationStep(1, "Ajouter les oeufs."),
new PreparationStep(2, "Ajouter la farine."),
new PreparationStep(3, "Mélanger le tout."),
new PreparationStep(4, "Faire cuire 1h10 au four traditionnel.")
}),
new Recipe(
title: "Gateau au chocolat",
preparationSteps: new[]{
new PreparationStep(1, "Ajouter les oeufs."),
new PreparationStep(2, "Ajouter la farine."),
new PreparationStep(2, "Ajouter 100g de chocolat fondu."),
new PreparationStep(3, "Mélanger le tout."),
new PreparationStep(4, "Faire cuire 45h au four traditionnel.")
}),
new Recipe(
title: "Gateau aux cerises",
preparationSteps: new[]{
new PreparationStep(1, "Ajouter les oeufs."),
new PreparationStep(2, "Ajouter la farine."),
new PreparationStep(2, "Ajouter des morceaux de fraises découpées en petits carré"),
new PreparationStep(3, "Mélanger le tout."),
new PreparationStep(4, "Faire cuire 30min au four traditionnel.")
}),
});
return stub;
}
public static List<RecipeCollection> LoadRecipeCollection()
{
List<RecipeCollection> stub = new List<RecipeCollection>();
stub.AddRange(new[]
{
new RecipeCollection("All", LoadRecipes().ToArray()),
new RecipeCollection("Starters", LoadRecipes().FindAll(x => x.Id.Equals(23)).ToArray()),
new RecipeCollection("Dishies", LoadRecipes().FindAll(x => x.Id.Equals(24)).ToArray()),
new RecipeCollection("Desserts", LoadRecipes().FindAll(x => x.Id.Equals(26)).ToArray()),
});
return stub;
}
public static List<User> ConstrucList()
{
List<User> Users = new List<User>();
User Roger = new User("Roger", "Rabbit", "carotte@mail.fr");
User Dylan = new User("d", "r", "dr@mail.fr");
User Val = new User("V", "entin", "Valentin@mail.fr");
Users.Add(Roger);
Users.Add(Dylan);
Users.Add(Val);
return Users;
}
}
}

@ -0,0 +1,111 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace DataPersistence
{
/// <summary>
/// Define a serializer to manage JSON files.
/// </summary>
public class DataContractJSON : IDataManager
{
#region Attributes
private string _jsonFolderPath;
private DataContractJsonSerializerSettings _dataContractJsonSerializerSettings;
#endregion
#region Constructors
/// <summary>
/// Constructor of the DataContractJSON serializer.
/// </summary>
/// <param name="jsonFolderPath">Give the default path where to load and save the data (by default is the current execution dir).</param>
/// <param name="dataContractJsonSerializerSettings">Give another set of DataContractJson serializer setting to write file</param>
public DataContractJSON(string jsonFolderPath = "",
DataContractJsonSerializerSettings? dataContractJsonSerializerSettings = null)
{
_jsonFolderPath = jsonFolderPath;
if (dataContractJsonSerializerSettings is null)
_dataContractJsonSerializerSettings = new DataContractJsonSerializerSettings()
{
KnownTypes = new[] { typeof(Recipe) }
};
else
_dataContractJsonSerializerSettings = dataContractJsonSerializerSettings;
}
#endregion
#region IDataManager implementation
public void Export<T>(T obj, string pathToExport)
where T : class
{
var jsonSerializer = new DataContractJsonSerializer(typeof(T), _dataContractJsonSerializerSettings);
using (FileStream stream = File.Create(Path.Combine(_jsonFolderPath, pathToExport)))
{
using (var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(
stream: stream,
encoding: System.Text.Encoding.UTF8,
ownsStream: false,
indent: true))
{
jsonSerializer.WriteObject(jsonWriter, obj);
}
}
}
public KeyValuePair<string, T> Import<T>(string pathToImport)
where T : class
{
T? obj;
var jsonSerializer = new DataContractJsonSerializer(typeof(T), _dataContractJsonSerializerSettings);
using (FileStream stream = File.OpenRead(Path.Combine(_jsonFolderPath, pathToImport)))
{
obj = jsonSerializer.ReadObject(stream) as T;
}
if (obj is null)
throw new ArgumentNullException("obj");
string typeName = typeof(T).Name;
return new KeyValuePair<string, T>(typeName, obj);
}
public Dictionary<string, List<object>> Load()
{
Dictionary<string, List<object>>? elements = new Dictionary<string, List<object>>();
var jsonSerializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<object>>), _dataContractJsonSerializerSettings);
using (FileStream stream = File.OpenRead(Path.Combine(_jsonFolderPath, "data.json")))
{
elements = jsonSerializer.ReadObject(stream) as Dictionary<string, List<object>>;
}
if (elements is null)
throw new ArgumentNullException("elements");
return elements;
}
public void Save(Dictionary<string, List<object>> elements)
{
var jsonSerializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<object>>), _dataContractJsonSerializerSettings);
using (FileStream stream = File.Create(Path.Combine(_jsonFolderPath, "data.json")))
{
using (var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(
stream: stream,
encoding: System.Text.Encoding.UTF8,
ownsStream: false,
indent: true))
{
jsonSerializer.WriteObject(jsonWriter, elements);
}
}
}
#endregion
}
}

@ -0,0 +1,115 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace DataPersistence
{
/// <summary>
/// Define a serializer to manage XML files.
/// </summary>
public class DataContractXML : IDataManager
{
#region Attributes
private string _xmlFolderPath;
private XmlWriterSettings _xmlWriterSettings;
private DataContractSerializerSettings _dataContractSerializerSettings;
#endregion
#region Constructors
/// <summary>
/// Constructor of a DataContractXML serializer.
/// </summary>
/// <param name="xmlFolderPath">Give the default path where to load and save the data (by default is the current execution dir).</param>
/// <param name="xmlWriterSettings">Give another set of XML setting to write file.</param>
/// <param name="dataContractSerializerSettings">Give another set of DataContract serializer setting to write file</param>
public DataContractXML(string xmlFolderPath = "",
XmlWriterSettings? xmlWriterSettings = null,
DataContractSerializerSettings? dataContractSerializerSettings = null)
{
_xmlFolderPath = xmlFolderPath;
if (xmlWriterSettings is null)
_xmlWriterSettings = new XmlWriterSettings() { Indent = true };
else
_xmlWriterSettings = xmlWriterSettings;
if (dataContractSerializerSettings is null)
_dataContractSerializerSettings = new DataContractSerializerSettings()
{
KnownTypes = new Type[] { typeof(Recipe) },
PreserveObjectReferences = true
};
else
_dataContractSerializerSettings = dataContractSerializerSettings;
}
#endregion
#region IDataManager implementation
public void Export<T>(T obj, string pathToExport)
where T : class
{
bool restore = _dataContractSerializerSettings.PreserveObjectReferences;
_dataContractSerializerSettings.PreserveObjectReferences = false;
var serializer = new DataContractSerializer(typeof(T), _dataContractSerializerSettings);
using (TextWriter textWriter = File.CreateText(Path.Combine(_xmlFolderPath, pathToExport)))
{
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, _xmlWriterSettings))
{
serializer.WriteObject(xmlWriter, obj);
}
}
_dataContractSerializerSettings.PreserveObjectReferences = restore;
}
public KeyValuePair<string, T> Import<T>(string pathToImport)
where T : class
{
T? obj;
var serializer = new DataContractSerializer(typeof(T), _dataContractSerializerSettings);
using (Stream s = File.OpenRead(Path.Combine(_xmlFolderPath, pathToImport)))
{
obj = serializer.ReadObject(s) as T;
}
if (obj is null)
throw new ArgumentNullException("obj");
string typeName = typeof(T).Name;
return new KeyValuePair<string, T>(typeName, obj);
}
public Dictionary<string, List<object>> Load()
{
Dictionary<string, List<object>>? elements;
var serializer = new DataContractSerializer(typeof(Dictionary<string, List<object>>), _dataContractSerializerSettings);
using (Stream s = File.OpenRead(Path.Combine(_xmlFolderPath, "data.xml")))
{
elements = serializer.ReadObject(s) as Dictionary<string, List<object>>;
}
if (elements is null)
throw new ArgumentNullException("elements");
return elements;
}
public void Save(Dictionary<string, List<object>> elements)
{
var serializer = new DataContractSerializer(typeof(Dictionary<string, List<object>>), _dataContractSerializerSettings);
using (TextWriter textWriter = File.CreateText(Path.Combine(_xmlFolderPath, "data.xml")))
{
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, _xmlWriterSettings))
{
serializer.WriteObject(xmlWriter, elements);
}
}
}
#endregion
}
}

@ -0,0 +1,81 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataPersistence
{
/// <summary>
/// Define the manager of the data. This is where all the data are put, and where we call the loading and the saving of them.
/// </summary>
public class DataManager
{
#region Attributes & Properties
/// <summary>
/// The data manager injected that know how to serialize the data.
/// <br/><remarks><i>The setter is actually public for testing purpose. It will be private after.</i></remarks>
/// <br/>See: <see cref="IDataManager"/>
/// </summary>
public IDataManager Serializer { get; set; }
/// <summary>
/// The collection of all data. Each line of this dictionary has the type of the data as it key and the data for values.
/// </summary>
public Dictionary<string, List<object>> Data { get; private set; }
#endregion
#region Constructors
/// <summary>
/// Constructor of the DataManager class. Take a IDataManager that will provide methods for the serialisation of the data.
/// </summary>
/// <param name="dataMgr">The data manager that know how to serialize a file.</param>
public DataManager(IDataManager dataMgr)
{
Serializer = dataMgr;
Data = Serializer.Load();
}
#endregion
#region Methods
/// <summary>
/// Reload the data. Useful to update new data written in the save file.
/// <br/>See: <see cref="IDataManager.Load"/>
/// </summary>
public void Reload()
=> Data = Serializer.Load();
/// <summary>
/// Save the data. Call the Save method of the serializer.
/// <br/>See: <see cref="IDataManager.Save(Dictionary{string, List{object}})"/>
/// </summary>
public void Save()
=> Serializer.Save(Data);
/// <summary>
/// Import data from a file.
/// <br/>See: <see cref="IDataManager.Import{T}(string)"/>
/// </summary>
/// <typeparam name="T">The type of data to import.</typeparam>
/// <param name="pathOfTheFile">The path containing the name of the file created.</param>
public void Import<T>(string pathOfTheFile)
where T : class
{
KeyValuePair<string, T> import = Serializer.Import<T>(pathOfTheFile);
Data[import.Key].Add(import.Value);
}
/// <summary>
/// Export the data from the collection of data.
/// <br/>See: <see cref="IDataManager.Export{T}(T, string)"/>
/// </summary>
/// <typeparam name="T">The type of data to export</typeparam>
/// <param name="obj">The object to export</param>
/// <param name="pathToExport">The path containing the name of the file created.</param>
public void Export<T>(T obj, string pathToExport)
where T : class
=> Serializer.Export<T>(obj, pathToExport);
#endregion
}
}

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

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataPersistence
{
/// <summary>
/// Interface that define the methods of a data serializer.
/// </summary>
public interface IDataManager
{
/// <summary>
/// Save all the data in a file.
/// </summary>
/// <param name="elements">The data to save.</param>
void Save(Dictionary<string, List<object>> elements);
/// <summary>
/// Load all the data from a file.
/// </summary>
/// <returns>The data loaded.</returns>
Dictionary<string, List<object>> Load();
/// <summary>
/// Import an element to the collection of data.
/// </summary>
/// <typeparam name="T">The type of the element to impoert</typeparam>
/// <param name="pathToImport">The path containing the name of the file.</param>
/// <returns>A pair where the key is the entry in the data and the value is the value to add on this entry.</returns>
public KeyValuePair<string, T> Import<T>(string pathToImport)
where T : class;
/// <summary>
/// Export an element from the collection of data.
/// </summary>
/// <typeparam name="T">The type of the exported object.</typeparam>
/// <param name="obj">The object to export.</param>
/// <param name="pathToExport">The path containing the name of the file created.</param>
public void Export<T>(T obj, string pathToExport)
where T : class;
}
}

@ -0,0 +1,112 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataPersistence
{
/// <summary>
/// The subs class is a group of prefabricated object that can only be loaded. It only use is for testing.
/// </summary>
public class Stubs : IDataManager
{
public Dictionary<string, List<object>> Load()
{
Dictionary<string, List<object>> data = new Dictionary<string, List<object>>
{
{
#region Data: Recipes
nameof(Recipe),
new List<object>(new[]
{
new Recipe(
title: "Cookies classiques", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Faire cuire."),
new PreparationStep(2, "Manger.")
}),
new Recipe(
title: "Cookies au chocolat", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Moulinez la pâte."),
new PreparationStep(2, "Faire cuire pendant une bonne heure."),
new PreparationStep(3, "Sortir du four et mettre dans un plat.")
}),
new Recipe(
title: "Gateau nature", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Achetez les ingrédients."),
new PreparationStep(2, "Préparez le matériel. Ustensiles et tout."),
new PreparationStep(3, "Pleurez.")
}),
new Recipe(
title: "Gateau au pommes", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Achetez les légumes."),
new PreparationStep(2, "Préparez le plat. Ustensiles et préchauffez le four."),
new PreparationStep(3, "Coupez les pommes en morceaux et disposez-les sur le plat."),
new PreparationStep(4, "Mettez enfin le plat au four, puis une fois cuit, dégustez !")
}),
new Recipe(
title: "Gateau au chocolat", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Ajouter les oeufs."),
new PreparationStep(2, "Ajouter la farine."),
new PreparationStep(3, "Ajouter 100g de chocolat fondu."),
new PreparationStep(4, "Mélanger le tout."),
new PreparationStep(5, "Faire cuire 45h au four traditionnel.")
}),
new Recipe(
title: "Dinde au jambon", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Faire une cuisson bien sec de la dinde à la poêle"),
new PreparationStep(2, "Mettre la dinde au frigo."),
new PreparationStep(3, "Mettre le jambon dans le micro-onde."),
new PreparationStep(4, "Faire chauffer 3min."),
new PreparationStep(5, "Présentez sur un plat la dinde et le jambon : Miam !")
}),
new Recipe(
title: "Poulet au curry", id: null,
preparationSteps: new[]
{
new PreparationStep(1, "Trouvez des épices de curry."),
new PreparationStep(2, "Trouvez maintenant du poulet."),
new PreparationStep(3, "Coupez la tête du poulet et posez-la dans un plat."),
new PreparationStep(4, "Parsemez d'épices curry la tête de la poule."),
new PreparationStep(5, "Mettre le tout au four traditionnel 30min."),
new PreparationStep(6, "Dégustez en famille !")
})
})
#endregion
}
};
return data;
}
#region Not supported methods
public void Save(Dictionary<string, List<object>> elements)
{
throw new NotSupportedException();
}
public void Export<T>(T obj, string pathToExport) where T : class
{
throw new NotSupportedException();
}
public KeyValuePair<string, T> Import<T>(string pathToImport) where T : class
{
throw new NotSupportedException();
}
#endregion
}
}

@ -0,0 +1,168 @@
[
{
"Key": "Recipe",
"Value": [
{
"__type": "recipe:#Model",
"id": 26700,
"preparation-steps": [
{
"description": "Faire cuire.",
"order": 1
},
{
"description": "Manger.",
"order": 2
}
],
"title": "Cookies classiques"
},
{
"__type": "recipe:#Model",
"id": 16433,
"preparation-steps": [
{
"description": "Moulinez la pâte.",
"order": 1
},
{
"description": "Faire cuire pendant une bonne heure.",
"order": 2
},
{
"description": "Sortir du four et mettre dans un plat.",
"order": 3
}
],
"title": "Cookies au chocolat"
},
{
"__type": "recipe:#Model",
"id": 26093,
"preparation-steps": [
{
"description": "Achetez les ingrédients.",
"order": 1
},
{
"description": "Préparez le matériel. Ustensiles et tout.",
"order": 2
},
{
"description": "Pleurez.",
"order": 3
}
],
"title": "Gateau nature"
},
{
"__type": "recipe:#Model",
"id": 21481,
"preparation-steps": [
{
"description": "Achetez les légumes.",
"order": 1
},
{
"description": "Préparez le plat. Ustensiles et préchauffez le four.",
"order": 2
},
{
"description": "Coupez les pommes en morceaux et disposez-les sur le plat.",
"order": 3
},
{
"description": "Mettez enfin le plat au four, puis une fois cuit, dégustez !",
"order": 4
}
],
"title": "Gateau au pommes"
},
{
"__type": "recipe:#Model",
"id": 15049,
"preparation-steps": [
{
"description": "Ajouter les oeufs.",
"order": 1
},
{
"description": "Ajouter la farine.",
"order": 2
},
{
"description": "Ajouter 100g de chocolat fondu.",
"order": 3
},
{
"description": "Mélanger le tout.",
"order": 4
},
{
"description": "Faire cuire 45h au four traditionnel.",
"order": 5
}
],
"title": "Gateau au chocolat"
},
{
"__type": "recipe:#Model",
"id": 28153,
"preparation-steps": [
{
"description": "Faire une cuisson bien sec de la dinde à la poêle",
"order": 1
},
{
"description": "Mettre la dinde au frigo.",
"order": 2
},
{
"description": "Mettre le jambon dans le micro-onde.",
"order": 3
},
{
"description": "Faire chauffer 3min.",
"order": 4
},
{
"description": "Présentez sur un plat la dinde et le jambon : Miam !",
"order": 5
}
],
"title": "Dinde au jambon"
},
{
"__type": "recipe:#Model",
"id": 8053,
"preparation-steps": [
{
"description": "Trouvez des épices de curry.",
"order": 1
},
{
"description": "Trouvez maintenant du poulet.",
"order": 2
},
{
"description": "Coupez la tête du poulet et posez-la dans un plat.",
"order": 3
},
{
"description": "Parsemez d'épices curry la tête de la poule.",
"order": 4
},
{
"description": "Mettre le tout au four traditionnel 30min.",
"order": 5
},
{
"description": "Dégustez en famille !",
"order": 6
}
],
"title": "Poulet au curry"
}
]
}
]

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfKeyValueOfstringArrayOfanyTypety7Ep6D1 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" z:Size="1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringArrayOfanyTypety7Ep6D1>
<Key z:Id="2">Recipe</Key>
<Value z:Id="3" z:Size="8">
<anyType z:Id="4" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>9062</d4p1:id>
<d4p1:preparation-steps z:Id="5" z:Size="2">
<d4p1:preparation-step z:Id="6">
<d4p1:description z:Id="7">Faire cuire.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="8">
<d4p1:description z:Id="9">Manger.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="10">Cookies classiques</d4p1:title>
</anyType>
<anyType z:Id="11" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>27627</d4p1:id>
<d4p1:preparation-steps z:Id="12" z:Size="3">
<d4p1:preparation-step z:Id="13">
<d4p1:description z:Id="14">Moulinez la pâte.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="15">
<d4p1:description z:Id="16">Faire cuire pendant une bonne heure.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="17">
<d4p1:description z:Id="18">Sortir du four et mettre dans un plat.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="19">Cookies au chocolat</d4p1:title>
</anyType>
<anyType z:Id="20" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>8517</d4p1:id>
<d4p1:preparation-steps z:Id="21" z:Size="3">
<d4p1:preparation-step z:Id="22">
<d4p1:description z:Id="23">Achetez les ingrédients.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="24">
<d4p1:description z:Id="25">Préparez le matériel. Ustensiles et tout.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="26">
<d4p1:description z:Id="27">Pleurez.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="28">Gateau nature</d4p1:title>
</anyType>
<anyType z:Id="29" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>6161</d4p1:id>
<d4p1:preparation-steps z:Id="30" z:Size="4">
<d4p1:preparation-step z:Id="31">
<d4p1:description z:Id="32">Achetez les légumes.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="33">
<d4p1:description z:Id="34">Préparez le plat. Ustensiles et préchauffez le four.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="35">
<d4p1:description z:Id="36">Coupez les pommes en morceaux et disposez-les sur le plat.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="37">
<d4p1:description z:Id="38">Mettez enfin le plat au four, puis une fois cuit, dégustez !</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="39">Gateau au pommes</d4p1:title>
</anyType>
<anyType z:Id="40" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>17869</d4p1:id>
<d4p1:preparation-steps z:Id="41" z:Size="5">
<d4p1:preparation-step z:Id="42">
<d4p1:description z:Id="43">Ajouter les oeufs.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="44">
<d4p1:description z:Id="45">Ajouter la farine.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="46">
<d4p1:description z:Id="47">Ajouter 100g de chocolat fondu.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="48">
<d4p1:description z:Id="49">Mélanger le tout.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="50">
<d4p1:description z:Id="51">Faire cuire 45h au four traditionnel.</d4p1:description>
<d4p1:order>5</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="52">Gateau au chocolat</d4p1:title>
</anyType>
<anyType z:Id="53" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>4810</d4p1:id>
<d4p1:preparation-steps z:Id="54" z:Size="5">
<d4p1:preparation-step z:Id="55">
<d4p1:description z:Id="56">Faire une cuisson bien sec de la dinde à la poêle</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="57">
<d4p1:description z:Id="58">Mettre la dinde au frigo.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="59">
<d4p1:description z:Id="60">Mettre le jambon dans le micro-onde.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="61">
<d4p1:description z:Id="62">Faire chauffer 3min.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="63">
<d4p1:description z:Id="64">Présentez sur un plat la dinde et le jambon : Miam !</d4p1:description>
<d4p1:order>5</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="65">Dinde au jambon</d4p1:title>
</anyType>
<anyType z:Id="66" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>13570</d4p1:id>
<d4p1:preparation-steps z:Id="67" z:Size="6">
<d4p1:preparation-step z:Id="68">
<d4p1:description z:Id="69">Trouvez des épices de curry.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="70">
<d4p1:description z:Id="71">Trouvez maintenant du poulet.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="72">
<d4p1:description z:Id="73">Coupez la tête du poulet et posez-la dans un plat.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="74">
<d4p1:description z:Id="75">Parsemez d'épices curry la tête de la poule.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="76">
<d4p1:description z:Id="77">Mettre le tout au four traditionnel 30min.</d4p1:description>
<d4p1:order>5</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="78">
<d4p1:description z:Id="79">Dégustez en famille !</d4p1:description>
<d4p1:order>6</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="80">Poulet au curry</d4p1:title>
</anyType>
<anyType z:Id="81" xmlns:d4p1="http://schemas.datacontract.org/2004/07/Model" i:type="d4p1:recipe">
<d4p1:id>26918</d4p1:id>
<d4p1:preparation-steps z:Id="82" z:Size="4">
<d4p1:preparation-step z:Id="83">
<d4p1:description z:Id="84">Achetez les ingrédients.</d4p1:description>
<d4p1:order>1</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="85">
<d4p1:description z:Id="86">Préparez le matériel. Ustensiles et tout.</d4p1:description>
<d4p1:order>2</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="87">
<d4p1:description z:Id="88">Pleurez.</d4p1:description>
<d4p1:order>3</d4p1:order>
</d4p1:preparation-step>
<d4p1:preparation-step z:Id="89">
<d4p1:description z:Id="90">Aprenez de vos echecs.</d4p1:description>
<d4p1:order>4</d4p1:order>
</d4p1:preparation-step>
</d4p1:preparation-steps>
<d4p1:title z:Id="91">Gateau nature v2</d4p1:title>
</anyType>
</Value>
</KeyValueOfstringArrayOfanyTypety7Ep6D1>
</ArrayOfKeyValueOfstringArrayOfanyTypety7Ep6D1>

@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
/// <summary>
/// Manager of the model. Here is stoked all the recipes, the users, etc...
/// </summary>
public class DataManager
{
/// <summary>
/// A collection of all the recipe loaded in the app.
/// </summary>
public RecipeCollection AllRecipes { get; protected set; }
/// <summary>
/// The constructor of the manager.
/// </summary>
public DataManager()
{
AllRecipes = new RecipeCollection(description: "All Recipes");
}
/// <summary>
/// The constructor of the manager.
/// </summary>
/// <param name="allRecipes">A list of loaded recipes</param>
public DataManager(RecipeCollection allRecipes)
{
AllRecipes = new RecipeCollection(
description: "All Recipes",
recipes: allRecipes.ToArray());
}
}
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
@ -9,6 +10,7 @@ namespace Model
/// <summary>
/// Define a step of the preparation of a recipe.
/// </summary>
[DataContract(Name = "preparation-step")]
public class PreparationStep : IEquatable<PreparationStep>
{
#region Attributes
@ -19,12 +21,14 @@ namespace Model
/// <summary>
/// The order of this step in the preparation of the meal.
/// </summary>
[DataMember(Name = "order")]
public int Order { get; init; }
/// <summary>
/// The description of the task the user need to do for this step of the preparation. <br/>
/// Set to "No description." when the value passed is null, empty or contain white spaces.
/// </summary>
[DataMember(Name = "description")]
public string Description
{
get => _description;

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
@ -9,9 +10,11 @@ namespace Model
/// <summary>
/// Define a Recipe for the preparation of a meal.
/// </summary>
[DataContract(Name = "recipe")]
public class Recipe : IEquatable<Recipe>
{
#region Attributes
[DataMember(Name = "title")]
private string _title = "";
#endregion
@ -19,6 +22,7 @@ namespace Model
/// <summary>
/// The ID of the recipe - allows you to compare and/or get this item in an easier way.
/// </summary>
[DataMember(Name = "id")]
public int Id { get; init; }
/// <summary>
@ -40,6 +44,7 @@ namespace Model
/// <summary>
/// The steps of the preparation. See: <see cref="PreparationStep"/>.
/// </summary>
[DataMember(Name = "preparation-steps")]
public List<PreparationStep> PreparationSteps { get; set; }
#endregion

@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model_UnitTests", "Tests\Mo
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{08B80CE8-A01D-4D86-8989-AF225D5DA48C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataPersistence", "DataPersistence\DataPersistence.csproj", "{432F9D12-B1F7-4A79-8720-4971BB10B831}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -37,6 +39,10 @@ Global
{45AB746A-194B-4E43-81EB-83B06F35AA33}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45AB746A-194B-4E43-81EB-83B06F35AA33}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45AB746A-194B-4E43-81EB-83B06F35AA33}.Release|Any CPU.Build.0 = Release|Any CPU
{432F9D12-B1F7-4A79-8720-4971BB10B831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{432F9D12-B1F7-4A79-8720-4971BB10B831}.Debug|Any CPU.Build.0 = Debug|Any CPU
{432F9D12-B1F7-4A79-8720-4971BB10B831}.Release|Any CPU.ActiveCfg = Release|Any CPU
{432F9D12-B1F7-4A79-8720-4971BB10B831}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -21,5 +21,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Model\Model.csproj" />
<ProjectReference Include="..\..\DataPersistence\DataPersistence.csproj" />
</ItemGroup>
</Project>
Loading…
Cancel
Save