Estoy aprendiendo c #. Estoy tratando de crear una lista básica en un repositorio falso (en lugar de saltar directamente a extraer datos de SQL). Tengo una lista que contiene autos y tiene campos como Id, Modelo, Marca, descripción, etc.

Luego estoy tratando de crear un método en mi clase Car.CS, de la cual obtengo el automóvil por Id. Por ejemplo, si paso la identificación del automóvil, devolverá los demás detalles del automóvil.

Desafortunadamente, cuando ejecuto la aplicación de consola, ¿simplemente vuelve en blanco en la consola? ¿Podría alguien decirme dónde me estoy equivocando, por favor?

En primer lugar tengo un ICarRepository

namespace GeneralConsoleApp
{
    interface ICarRepository
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
    }
}

Y luego tengo mi MockCarRepository del cual contiene la lista

namespace GeneralConsoleApp
{
    class MockCarRepository : ICarRepository
    {
        public IEnumerable<Car> Cars =>
            new List<Car>
            {
                new Car {Id = 1, Name="BMW", Price=23000.00M, Description="BMW car" }
            };

        public int Id { get; set; }
        public string Name {get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
    }
}

La siguiente es mi Car.cs

namespace GeneralConsoleApp
{
    class Car
    {
        private readonly List<Car> CarList = new List<Car>();

        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Description { get; set; }

        public Car GetCarById(int Id)
        {
            return CarList.FirstOrDefault(z => z.Id == Id);

        }
    }
}

Y finalmente mi método principal program.cs

namespace GeneralConsoleApp
{
    class Program
    {

        static void Main()
        {
            Car car = new Car();


            Console.WriteLine(car.GetCarById(1));

            Console.ReadLine();
        }
    }
}
c#
-1
Matty21202 22 abr. 2020 a las 11:20

5 respuestas

La mejor respuesta

Algunas cuestiones aquí con respecto a la separación de las preocupaciones. Su modelo de automóvil solo necesita modelar las propiedades asociadas con un automóvil.

Del mismo modo, su CarRepository debe contener solo los métodos necesarios para realizar consultas en su almacén de datos, como

GetCarById(int id)

O

IEnumberable<Car> FindByManufacturer(string manufacturer);

En términos de burlarse de su almacén de datos, crearía una clase específicamente para burlarse, como MockCarRepository, y luego, en tiempo de ejecución, puede crear una instancia. La razón por la que esto es muy útil es que, en última instancia, al programar contra la interfaz ICarRepository, cuando esté listo para usar datos reales, todo lo que necesita hacer es crear una nueva implementación de su ICarRepository, utilizando cualquier tienda que desee, conexión SQL nativa , EntityFramework, CosmosDB, etc., y simplemente cambie dónde está creando instancias de su tipo para satisfacer el ICarRepository.

Le recomendaría que estudie los principios de diseño SÓLIDO: un excelente recurso a continuación, que explica las cosas mucho mejor que yo.

https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/may/csharp-best-practices-dangers-of-violating-solid-principles-in-csharp

Con algunos pequeños ajustes, podría usar algo como lo siguiente.

namespace GeneralConsoleApp
{
interface ICarRepository
{
    Car GetCarById(int id);
}

class MockCarRepository : ICarRepository
{
    private List<Car> _mockCars;

    public MockCarRepository()
    {
        _mockCars = new List<Car>
        {
            new Car {Id = 1, Name="BMW", Price=23000.00M, Description="BMW car" }
        };
    }

    public Car GetCarById(int id)
    {
        return _mockCars.FirstOrDefault(v => v.Id == id);
    }
}

class SqlCarRepository : ICarRepository
{
    private readonly string _connectionString;

    public SqlCarRepository(string connectionString)
    {
        _connectionString = connectionString;
    }

    public Car GetCarById(int id)
    {
        // use the _connectionString to create your database connection.
        var car = FROM DATABASE;
        return car;
    }
}

class Car
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Description { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // All repositories should implement ICarRepository
        // meaning switching repo implementation is a one line change below, a DI container adjustment, or some sort of strategy pattern.
        ICarRepository mockRepo = new MockCarRepository();;

        var carFound = mockRepo.GetCarById(1);

        Console.WriteLine("Found car: " + carFound.Description);

        Console.ReadLine();

    }
}

}

0
Phil 23 abr. 2020 a las 06:10

Su clase Car no utiliza MockCarRepository sino que tiene su propia lista vacía (CarList).

Debería completar la lista en Car o usar el repositorio simulado allí.

1
Ilya Chernomordik 22 abr. 2020 a las 08:26

Su problema es que su clase de Automóvil tiene una lista de tipos de Automóvil desde los cuales está devolviendo un valor a la consola.

En su lugar, debería devolver un valor del Repositorio.

nammespace GeneralConsoleApp
{
    class MockCarRepository : ICarRepository
    {
           public IEnumerable<Car> Cars => new List<Car>
           {
                   new Car {Id = 1, Name="BMW", Price=23000.00M, Description="BMW car" }
           };

           public Car GetCarById(int Id)
           {
             return Cars.FirstOrDefault(z => z.Id == Id);
           }
    }
    class Program
    {
        static void Main()
        {
            var Repository = new MockRepository();


            Console.WriteLine(Repository.GetCarById(1));

        }
    }
}
0
ChrisBD 22 abr. 2020 a las 08:33

Deberías hacer algo como

ICarRepository repository= new MockCarRepository();
CarService carService= new CarService(repository);
Console.WriteLine(carService.GetCarById(1));

Debería agregar la clase CarService que puede inyectar el repositorio simulado o el repositorio de base de datos real y modificar la clase Car para que sea un modelo.

    class CarService
    {
        private readonly ICarRepository _repository;
        public CarService(ICarRepository repository)
        {
           _repository=repository;
        }

        public Car GetCarById(int Id)
        {
            return _repositoy.GetCarById(id);    
        }
    }

    class Car
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Description { get; set; }       
    }
    interface ICarRepository
    {
        Car GetCarById(int Id);
    }
    class MockCarRepository : ICarRepository
    {
        public IEnumerable<Car> Cars =>
            new List<Car>
            {
                new Car {Id = 1, Name="BMW", Price=23000.00M, Description="BMW car" }
            };
        public Car GetCarById(int Id)
        {
            return Cars.First(z => z.Id == Id);    
        }
    }
0
Deepak Mishra 22 abr. 2020 a las 08:56

CarList es una lista vacía y esa es la razón de no tener salida.

Cambiar llamada principal a

MockCarRepository car = new MockCarRepository();
Console.WriteLine(car.GetCarById(1).Name);

Y verás la diferencia.

0
user2316116 22 abr. 2020 a las 08:31