Il s'agit peut-être davantage d'une question de révision de code que d'un dépassement de pile.Modèle de conception de référentiel avec Dapper
J'utilise Dapper pour un MicroORM pour récupérer et enregistrer des données dans SQL Server 2014. J'ai des classes DTO dans un projet DTO qui représentent les données extraites de la base de données ou enregistrées dans la base de données. J'utilise le Repository Pattern donc à ma couche Service si un référentiel est requis J'utilise le constructeur DI pour injecter cette dépendance et ensuite appeler la méthode sur le Repository pour faire le travail. Alors disons que j'ai 2 services appelés CustomerService et CarService. J'ai ensuite 2 dépôts dans CustomerRepository et un CarRepository.
J'ai une interface qui définit toutes les méthodes dans chaque Repository puis les implémentations concrètes.
Un exemple de procédé est illustré ci-dessous (appeler un proc stocké pour faire le DB INSERT (notez la variable de chaîne réelle pour la procédure stockée est définie comme une chaîne privée en haut de la classe):
public void SaveCustomer(CustomerDTO custDTO)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
{
db.Execute(saveCustSp, custDTO, commandType: CommandType.StoredProcedure);
}
}
Tout cela fonctionne bien mais je me retrouve à répéter le bloc using dans chaque méthode dans chaque référentiel.J'ai deux vraies questions décrites ci-dessous:
Y at-il une meilleure approche que je pourrais utiliser peut-être en quelque sorte en utilisant une classe BaseRepository tous les autres référentiels héritent de et la base implémenterait l'instanciation de la connexion DB ?
Cela fonctionnerait-il encore correctement pour plusieurs utilisateurs simultanés sur le système?
**** **** MISE A JOUR
Sur la base de réponse Silas J'ai créé le
suivantpublic interface IBaseRepository
{
void Execute(Action<IDbConnection> query);
}
public class BaseRepository: IBaseRepository
{
public void Execute(Action<IDbConnection> query)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
{
query.Invoke(db);
}
}
}
Cependant, dans mes dépôts, j'ai d'autres méthodes telles que le ci-dessous:
public bool IsOnlyCarInStock(int carId, int year)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
{
var car = db.ExecuteScalar<int>(anotherStoredSp, new { CarID = carId, Year = year },
commandType: CommandType.StoredProcedure);
return car > 0 ? true : false;
}
}
et
public IEnumerable<EmployeeDTO> GetEmployeeDetails(int employeeId)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
{
return db.Query<EmployeeDTO>(anotherSp, new { EmployeeID = employeeId },
commandType: CommandType.StoredProcedure);
}
}
Quelle est la bonne façon de les ajouter à mon dépôt de base en utilisant le type générique T afin que je puisse retourner n'importe quel type de DTO ou n'importe quel C#
C'est la façon de le réaliser, vous devez rendre votre BaseRepository jetable pour disposer de votre IDbConnection. Vous pouvez jeter un œil sur l'utilisation du modèle de référentiel et du modèle d'unité de travail dans la documentation Microsoft https://docs.microsoft.com/fr-fr/aspnet/mvc/overview/older-versions/getting-started-with-ef- 5-using-mvc-4/implementation-le-repository-et-unit-of-work-patterns-in-an-asp-net-mvc-application – OrcusZ
le bloc 'using' est un mal nécessaire parce que vous ouvrez les connexions à la base de données qui doivent être fermées. Donc la répétition est nécessaire. Je suggérerais seulement de ne pas être pris dans toute la substance modèle de conception de dépôt .... –
@ Callum - quel autre modèle suggéreriez-vous ou pourriez-vous illustrer avec un exemple. J'avais regardé en utilisant CQRS mais je me sentais référentiel comme ci-dessus travaillé pour moi basé sur KISS –