Autofixture: Acusa a Readonly por una propiedad que no es ReadOnly

Creado en 4 jun. 2013  ·  4Comentarios  ·  Fuente: AutoFixture/AutoFixture

En mi capa de dominio tengo la clase:

public class Telefone : IEntity
{
    public virtual int Id { get; protected internal set; }
    public virtual string Tipo { get; set; }
    public virtual string Numero { get; set; }
}

La identificación está protegida internamente. Esto es deliberado, quien genera el Id es la base de datos y debe ser de solo lectura.
Pero en la capa de prueba, debe tener acceso al establecedor de esta propiedad.

Entonces, en mi capa de dominio agregué el atributo en AssemblyInfo.cs:

[assembly: InternalsVisibleTo("MyTestLayer")]

¡Esto me permitirá establecer el Id en la capa de pruebas pero no en la capa de dominio!

En capa de prueba
nuevo Telefone (). Id = 1; // ¡¡Obras!!

En la capa de la interfaz de usuario
nuevo Telefone (). Id = 1; // ¡No compilar! ¡No funciona!

Problema

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();

Teóricamente, el código anterior debería funcionar, pero cuando mi prueba de carretera ocurre un error:

La propiedad "Id" es de solo lectura.

Todas las propiedades Id s son protected internal .

En el mismo archivo, la misma prueba puede hacer algo como:

nuevo Telefone (). Id = 1; // ¡¡Obras!!
nuevo correo electrónico (). Id = 1; // ¡¡Obras!!

question

Todos 4 comentarios

Esto le dice claramente que tiene una _ abstracción con fugas_ en su modelo de dominio. Un modelo de dominio no debe diseñarse teniendo en cuenta ninguna tecnología de límites en particular.

Este problema en particular le dice claramente que su modelo de dominio _no_ es reutilizable.

InternalsVisibleTo no tiene ningún efecto porque solo permite el acceso a su biblioteca de prueba, pero AutoFixture es un ensamblaje completamente diferente. Esto solo le dice que _ ningún otro cliente podrá reutilizar su modelo de dominio.

El mejor curso de acción es reconsiderar el diseño de su API. Normalmente, haría algo como esto:

`` c #
Telefone de clase pública: IEntity
{
telefono publico (int id)
{
this.Id = id;
}

public virtual int Id { get; private set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }

}
''

Esto generó mucha discusión en un grupo de arquitectura que sigo.
Hay un problema importante con este enfoque:

  1. Quien se encarga de generar el Id es la base de datos, solo se genera cuando se guarda el objeto.
  2. Cuando creo un nuevo objeto, ¿cuál Id debe pasar en el constructor? No puedo poner el Id en el constructor.
  3. El Id es un int secuencial. La capa de repositorio es la capa más cercana del dominio. Para generar el Id haría algo como max (id) + 1 y luego establecer el Id de mi objeto. Pero, ¿cómo configurar el Id si es de solo lectura?
  4. La única forma de establecer el Id de en una propiedad ReadOnly es dentro de la propia clase o usando un proxy / reflejo

Estuvo de acuerdo en que todos estos son _problemas_. Los cuatro _fuertemente_ indican que el modelo de dominio depende de la capa de persistencia y no se puede hacer funcionar sin ella.

  1. ¿Por qué la base de datos debería asignar ID? El único requisito es que una identificación sea única. Por eso tenemos GUID.
  2. Pase una nueva instancia de Guid al constructor.
  3. ¿Por qué la identificación es secuencial? Rara vez hay una razón arquitectónica para que los ID sean secuenciales.
  4. Acordado. Hay una razón por la que existen modificadores de acceso.

Entiendo el problema. No puedo cambiar el tipo de PK a Guid, realmente funcionaría.

Entiendo ahora que el problema no está relacionado con AutoFixture, pero si está interesado. Creo un proyecto de muestra para discutir esto.

Gracias.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

zvirja picture zvirja  ·  8Comentarios

ploeh picture ploeh  ·  7Comentarios

tiesmaster picture tiesmaster  ·  7Comentarios

Ephasme picture Ephasme  ·  3Comentarios

JoshKeegan picture JoshKeegan  ·  6Comentarios