Подходящий дизайн для Entity Framework и структуры приложений ASP .NET - PullRequest
0 голосов
/ 09 июля 2019

В настоящее время я пытаюсь понять, как лучше структурировать свой код для приложений ASP.NET, но мне неясно, в каком направлении мне следует идти. Мне было интересно, смогу ли я получить некоторое представление о том, что у меня есть до сих пор, чтобы увидеть, нахожусь ли я на правильном пути, или я полностью пропустил цель.

Из того, что я почерпнул из своего исследования:

  • Кажется, что шаблон репозитория является спорным, так как Entity Framework уже делает свою собственную псевдо-реализацию. Общее согласие просто использовать Entity Framework напрямую, а не добавлять ненужные абстракции, если только вы не планируете использовать другую среду, кроме Entity Framework.

  • Сервисный уровень / шаблоны используют репозитории для реализации бизнес-логики и, вероятно, будет лучше, чем использование репозиториев с учетом структуры Entity Framework.

В настоящее время я рассматриваю следующий дизайн, но я не совсем уверен, подходит ли это или хорошая практика в долгосрочной перспективе;

public class Manufacturer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public string Website { get; set; }
}

public class Asset
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public int ManufacturerId { get; set; }

    public virtual Manufacturer Manufacturer { get; set; }
}

// Generic Queries used within views for select lists and lookups.
public static class GenericManufacturerQueries
{
    public static List<Manufacturer> GetAll(InventoryDb context)
    {
        return context.Manufacturer.ToList();
    }

    public static List<Manufacturer> GetById(int id, InventoryDb context)
    {
        return context.Manufacturer.Where(x => x.Id == id).FirstOrDefault();
    }

    ...omitted for brevity...
}

// Service class to facilitate Create/Update/Delete for each primary entity.
// Code could be too long for posting but the omitted sections also include
// creating/writing differences to a log of the sort. Hence, service classes
// also operate on auxiliary entities. 
public class AssetService
{
    private InventoryDbContext _context = null;

    public AssetService(InventoryDb context)
    {
        _context = context;
    }

    public void AddAsset(Asset model)
    {
        ...omitted for brevity...
    }

    public void RemoveAsset(int assetId)
    {
        ...omitted for brevity...
    }

    public void UpdateAsset(Asset model)
    {
        ...omitted for brevity...
    }
}

Возможное использование в модели представления:

public class AssetCreateVM
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public ManufacturerId { get; set; }

    public List<SelectListItem> Manufacturers
    {
        get
        {
            using(var context = new InventoryDbContext())
            {
                  return GenericModelQueries.GetAll(context)
                                            .Select(x => new  SelectListItem() { Text = x.Name, Value = x.Id }).ToList();
            }
        }
  }

  public void SaveModel()
  {
      using(var context = new InventoryDbContext())
      {
          AssetService service = new AssetService(context);
          var model = new Asset()
                          {
                               Name = this.Name,
                               Description = this.Description,
                               ManufacturerId = this.ManufacturerId,
                          };

            service.AddAsset(model);
        }
    }
}

Что касается дизайна, мои мысли в то время были следующими:

  • У меня есть классы сущностей на уровне данных для каждой из моих таблиц базы данных. Доступ к операции CRUD управляется через DbContext Entity Framework.

  • Для обобщенных запросов я рассматриваю объединение их в один статический / обобщенный класс, который не нужно создавать, чтобы избежать переписывания кода. Чтобы поддерживать согласованную / актуальную транзакцию, я передаю контекст в качестве аргумента каждой функции в классах.

  • С сервисами, инкапсулирующими операции CRUD, я потенциально могу повторно использовать логику в других модулях и областях моих приложений, кроме моих View Models.

  • Я смотрю на возможное написание тестов для сервисов, вводя их в фиктивном контексте через библиотеку Entity Effort, но я не уверен, как я это сделаю на этом этапе.

Спасибо за ваше время.

...