# ex_041_004_InMemory
*31/12/2019 &sdot; Marc Chevaldonné*  

---

Le fournisseur **InMemory** est utilisé pour tester des bases de données sans avoir à créer réellement une base de données.
Ceci permet de tester les accès à votre "base" de manière toutefois approximative.
En effet, **InMemory** n'est pas une base de données relationnelle : il y a donc des limitations.  
Cet exemple montre comment utiliser **InMemory** à travers une injection de dépendance. En d'autres termes, vous continuez à définir votre chaîne de connexion sur une base de données, mais vous permettez néanmoins l'utilisation, à la demande, de **InMemory** pour des tests.  
Puisque ce fournisseur devient intéressant dans le cas de tests, j'ai donc ajouté un 2ème projet lié à cet exemple, permettant d'avoir accès à des tests unitaires utilisant **InMemory**.  
Pour le reste de l'exemple, celui-ci n'apporte rien de nouveau par rapport à l'exemple ex_041_001.
  
---

## Comment a été construit cet exemple ?
Cet exemple est tout d'abord construit de la même manière que l'exemple *ex_041_001_ConnectionStrings*.
Il ne faut pas oublier les NuGet nécessaires :
* Microsoft.EntityFrameworkCore : pour le projet en général
* Microsoft.EntityFrameworkCore.SqlServer : pour le *provider* SQL Server
* Microsoft.EntityFrameworkCore.Tools : pour bénéficier des outils de Design, de migrations, etc.  
  
J'ai ensuite décidé de renommer ma classe dérivant de ```DbContext``` en ```NounoursContext``` car je n'ai plus de raison de faire la différence entre SqlServer et SQLite.  
On obtient ainsi la classe ```NounoursContext``` suivante :
```csharp
using Microsoft.EntityFrameworkCore;

namespace ex_041_004_InMemory
{
    public class NounoursContext : DbContext
    {
        public DbSet<Nounours> Nounours { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ex_041_004_InMemory.Nounours.mdf;Trusted_Connection=True;");
    }
}
```
On la modifie pour permettre d'injecter un autre fournisseur, tout en gardant celui-ci par défaut. On peut utiliser pour cela la propriété ```IsConfigured``` sur ```DbContextOptionsBuilder```.  
La méthode ```OnConfiguring``` de ```NounoursContext``` est alors modifiée de la manière suivante  :
```csharp
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
    if (!options.IsConfigured)
    {
        options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ex_041_004_InMemory.Nounours.mdf;Trusted_Connection=True;");
    }
}
``` 
  
Dès lors, si rien n'est configuré, c'est donc le fournisseur *SqlServer* qui sera utilisé.  
Mais nous pouvons aussi permettre à l'utilisateur d'en injecter un autre. Pour cela, nous ajoutons deux constructeurs à notre classe :
* ```NounoursContext()``` : le constructeur par défaut ne fait rien, et en conséquence fera que la configuration *SqlServer* sera utilisée,
* ```NounoursContext(DbContextOptions<NounoursContext> options)``` : ce constructeur par défaut permettra d'injecter une autre fabrique de fournisseur, et permettra à l'utilisateur d'injecter n'importe quel autre fournisseur, dont **InMemory**.  
  
Les constructeurs injectés sont donc :
```csharp
public NounoursContext()
{ }

public NounoursContext(DbContextOptions<NounoursContext> options)
    : base(options)
{ }
```
La classe ```NounoursContext``` peut donc s'utiliser comme précédemment, sans changement, et la base *SqlServer* sera utilisée ; ou alors, on pourra injecter un autre fournisseur.

## Configuration du test unitaire
Le test unitaire est de type *xUnit* et va permettre d'injecter le fournisseur **InMemory**.
  

test
* nouveau projet
* dépendances
* nuget
* écriture du test