Dans ma couche de domaine, j'ai la classe :
public class Telefone : IEntity
{
public virtual int Id { get; protected internal set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }
}
L'identifiant est protégé en interne. Ceci est délibéré, qui génère l'ID est la base de données et doit être en lecture seule.
Mais dans la couche de test, il faut avoir accès au setter de cette propriété.
Donc, dans ma couche de domaine, j'ai ajouté l'attribut dans AssemblyInfo.cs :
[assembly: InternalsVisibleTo("MyTestLayer")]
Cela me permettra de définir l'Id dans la couche de tests mais pas dans la couche de domaine !
Dans la couche de test
nouveau Telefone().Id = 1; // Travaux!!
Dans la couche d'interface utilisateur
nouveau Telefone().Id = 1; // Pas de compilation ! Ne fonctionne pas !
var pessoa = fix.Build<Pessoa>()
.With(p => p.Nome)
.Do((pess) =>
{
fix.Build<Telefone>()
.With(p => p.Id)
.With(p => p.Tipo)
.With(p => p.Numero)
.OmitAutoProperties()
.CreateMany(10).ToList().ForEach(pess.Telefones.Add);
fix.Build<Email>()
.With(p => p.Id)
.With(p => p.Tipo)
.With(p => p.Endereco)
.OmitAutoProperties()
.CreateMany(10).ToList().ForEach(pess.Emails.Add);
})
.OmitAutoProperties()
.Create();
Théoriquement, le code ci-dessus devrait fonctionner, mais lors de mon essai routier une erreur se produit :
La propriété "Id" est en lecture seule.
Toutes les propriétés Id
s sont protected internal
.
Dans le même fichier, le même test peut faire quelque chose comme :
nouveau Telefone().Id = 1; // Travaux!!
nouvel e-mail().Id = 1 ; // Travaux!!
Cela vous indique clairement que vous avez une _abstraction qui fuit_ dans votre modèle de domaine. Un modèle de domaine ne doit pas être conçu avec une technologie de limite particulière à l'esprit.
Ce problème particulier vous indique très clairement que votre modèle de domaine n'est _pas_ réutilisable.
InternalsVisibleTo
n'a aucun effet car il permet uniquement l'accès à votre bibliothèque de test, mais AutoFixture est un assembly entièrement différent. Cela vous indique simplement que _aucun_ autre client ne pourra jamais réutiliser votre modèle de domaine.
La meilleure chose à faire est de reconsidérer la conception de votre API. Normalement, je ferais quelque chose comme ça :
``` c#
Téléphone de classe publique : IEntity
{
Téléphone public(int id)
{
this.Id = id;
}
public virtual int Id { get; private set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }
}
```
Cela a généré beaucoup de discussions dans un groupe d'architecture que je suis.
Il y a un problème majeur avec cette approche :
max (id) + 1
, puis définir l'Id de mon objet. Mais comment définir l'Id s'il est en lecture seule ?Convenu que ce sont tous des _problèmes_. Tous les quatre indiquent _fortement_ que le modèle de domaine dépend de la couche de persistance et ne peut pas fonctionner sans elle.
Je comprends le problème. Je ne peux pas changer le type PKs en Guid, cela fonctionnerait vraiment.
Je comprends maintenant que le problème n'est pas lié à AutoFixture, mais si cela vous intéresse. Je crée un exemple de projet pour en discuter.
Merci.