web-dev-qa-db-fra.com

Structure / meilleures pratiques du projet Blazor

Mon entreprise passe d'une base de code héritée à une plate-forme plus moderne et nous passons à Blazor. Nous commençons actuellement à nous impliquer dans les ORM et les meilleures pratiques et il semble y avoir beaucoup d'idées contradictoires concernant la configuration du projet (du moins d'après ce que j'ai rassemblé). Ma structure actuelle est la suivante:

La première est une bibliothèque de classes appelée DAL - C'est notre "couche de données". Nous utilisons Dapper et c'est relativement simple. Un exemple de classe ressemblerait à ceci:

public class Person
{
      public string Id {get; set;}
      public string FirstName {get; set;}
      public string LastName {get; set;}

      public Person() {}
      public Person(DbContext context) {}

      public void GetPerson(int id) {}
      public void DeletePerson(int id) {}


      etc....
}

Le deuxième projet est un serveur Blazor Project qui fait référence au projet DAL. Le projet est divisé comme tel:

  1. Modèles - Ce sont des modèles SPÉCIFIQUES au projet en cours d'élaboration. Par exemple, un modèle peut être une combinaison de plusieurs tables (modèles de la classe DAL) ou simplement des champs utilisés pour un formulaire sur une page Web.

Un exemple pourrait ressembler à ceci:

public class EmployeeModel
{
    public int Id {get; set;}
    public int Department{get; set;}
    public DateTime HireDate {get; set;}
    public decimal Salary {get; set;}
    public Person {get; set;}
}
  1. Pages - Pages/composants de rasoir avec une référence de page.
  2. Partagé - Composants Razor - éléments utilisés sur plusieurs pages. Un exemple serait un modal.
  3. Services - C'est, je suppose, la couche métier. Pour l'instant, il existe un service par modèle/classe dans le dossier "Modèles" mais il y en a aussi pour les composants partagés. Un exemple pour le EmployeeModel du dossier Models, pourrait être en tant que tel:
public class EmployeeService
{
    private DbContext _dbContext = dbContext;
    public EmployeeService(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public Task<EmployeeModel> Get(int id)
    {
        var personRepository = new Person(_dbContext);
        var person = personRepository.Get(id);
        Id = id;
        if (id > 10)
            Department = "Accounting"
        etc...
    }

    public Task<int>CalculateBonus(DateTime hireDate, string department, decimal salary)
    {
         //logic here...
    }
}

Les services et dbcontext sont tous générés via l'injection de dépendances via startup.cs. La classe de page chargerait les données avec quelque chose comme ceci:


@code{

    [Parameter]
    int EmployeeId;

    public Employee employee;
    public decimal bonus;

    protected override OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender)
            return;

        employee = EmployeeService.Get(EmployeeId);
    }

    public void GetBonus()
    {
        if (employee != null)
            bonus = EmployeeService.CalculateBonus(employee.HireDate, employee.Department, employee.Salary) 
    }
}

Cela semble aller bien jusqu'à présent, mais il existe BEAUCOUP d'interprétations différentes. Par exemple, j'ai aimé l'idée d'utiliser un modèle MVVM. Un exemple que je suivais à l'origine était le suivant: https://itnext.io/a-simple-mvvm-implementation-in-client-side-blazor-8c875c365435

Cependant, je ne voyais pas le but de séparer Model/ViewModel de la façon dont ils étaient dans cet exemple, car ils semblaient faire la même chose mais juste dans différentes zones de l'application. Je n'ai pas non plus pu trouver d'autres exemples de cette implémentation en ligne.Je pensais donc que je me dirigeais dans la mauvaise direction et j'ai d'abord abandonné cela, mais je suis encore assez tôt dans le processus pour essayer cette méthode également. Par exemple, la classe EmployeeService ressemblerait à ceci dans cette méthode:

public class EmployeeService
{
    private EmployeeModel _employeeModel;
    public EmployeeService(EmployeeModel employeeModel)
    {
        _employeeModel = employeeModel;
    }

    private EmployeeModel currentEmployee;
    public EmployeeModel CurrentEmployee
    {
        get { return currentEmployee}
    }
    {
        set {currentEmployee = value; }
    }

    public Task<EmployeeModel> Get(int id)
    {
         currentEmployee = EmployeeModel.Get(id);
    }

    public Task<int>CalculateBonus()
    {
         //logic implemented here with properties instead of parameters... 
    }
}

Ensuite, sur la page, ce serait comme suit:


@code{

    [Parameter]
    int EmployeeId;
    public decimal bonus;

    protected override OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender)
            return;

        EmployeeService.Get(EmployeeId); //reference Employee on page with EmployeeService.CurrentEmployee
    }

    public void GetBonus()
    {
        bonus = EmployeeService.CalculateBonus();
    }
}

Voyant comment je travaillais avec le code hérité depuis si longtemps et sans personne senior pour me dire le contraire, je veux juste savoir que je le fais bien. Cela est particulièrement vrai car cela est censé être le cœur de notre entreprise pour aller de l'avant et je ne veux pas me retrouver avec du code spaghetti ou faire un refactor complet sur toute la ligne.

Je suppose que mes questions sont les suivantes:

  1. Comment est ma mise en œuvre actuelle d'un DAL? Est-il acceptable que les propriétés réelles soient conformes aux opérations CRUD? Comme avoir un constructeur avec le DBContext et un sans? J'ai vu certains projets avoir une bibliothèque séparée juste pour la classe sans les opérations CRUD et je n'ai pas vu la valeur de cela. La logique derrière cela est que la plupart de nos applications ne sont que des opérations CRUD, donc j'aimerais pouvoir réutiliser ce projet dans chaque application à l'avenir. De la recherche en ligne, cette implémentation est un hybride d'un DAL/BLL

    1. Mon implémentation actuelle de Blazor "fonctionne"? Ou existe-t-il d'autres meilleures pratiques de conception que je peux suivre? J'aime MVVM, mais je ne vois vraiment pas la valeur dans les implémentations que j'ai vues jusqu'à présent. Quel est l'intérêt d'avoir une page appeler une fonction sur un ViewModel, qui appelle juste une fonction dans une autre classe avec le même nom/paramètres? Ne serait-il pas logique de couper l'homme du milieu pour ainsi dire?

    2. Y a-t-il des exemples de projets d'entreprise que je pourrais suivre pour avoir une meilleure idée de ce que je dois faire ici? Comme je l'ai dit, il n'y a pas de cadre supérieur dans mon entreprise où aller pour tout cela. J'essaie juste de le rendre aussi adaptable au changement/professionnel que possible.

Merci d'avance pour l'aide!

6
Dan

Tout en travaillant avec une architecture à trois niveaux, je vois que la couche métier va croître et un certain moment devient très compliqué et se couple étroitement.

Je recommanderais d'essayer Onion Architecture , son très populaire et très similaire à Clean Architecture .

Je suis sûr que vous cherchez un exemple d'application pour voir comment garder chaque couche séparée, quelles sont les meilleures pratiques et les meilleures bibliothèques.

Essayez le lien ci-dessous, vous obtiendrez beaucoup de vidéos sur youtube.

passe-partout Asp.net

ABP Framework

Étant donné que Blazor Web Assembly est toujours en version préliminaire, je démarre la migration de mon site Web personnel d'asp.netcore 2.0 vers le côté client Blazor et la fonction Azure pour le côté serveur.

Voici ma structure d'application

enter image description here

J'espère que cela aidera!

0
Pankaj Rawat