Je suis en train de concevoir une solution à n niveaux qui utilise Entity Framework 5 (.net 4) comme stratégie d'accès aux données, mais je me demande comment incorporer l'injection de dépendance pour la rendre testable / flexible.
Ma disposition actuelle de la solution est la suivante (ma solution s'appelle Alcatraz):
Alcatraz.WebUI : un projet de formulaire Web asp.net, l'interface utilisateur frontale, fait référence aux projets Alcatraz.Business et Alcatraz.Data.Models .
Alcatraz.Business : projet de bibliothèque de classes, contient la logique métier, fait référence aux projets Alcatraz.Data.Access , Alcatraz.Data.Models
Alcatraz.Data.Access : Un projet de bibliothèque de classe, qui héberge AlcatrazModel.edmx et AlcatrazEntities
DbContext, fait référence aux projets Alcatraz.Data.Models .
Alcatraz.Data.Models : projet de bibliothèque de classes, contient des POCO pour le modèle Alcatraz, sans références.
Ma vision du fonctionnement de cette solution est que l'interface utilisateur Web instancierait un référentiel au sein de la bibliothèque d'entreprise, ce référentiel aurait une dépendance (via le constructeur) d'une chaîne de connexion (pas une AlcatrazEntities
instance). L'interface Web connaîtrait les chaînes de connexion à la base de données, mais pas qu'il s'agissait d'une chaîne de connexion de structure d'entité.
Dans le projet Business:
public class InmateRepository : IInmateRepository
{
private string _connectionString;
public InmateRepository(string connectionString)
{
if (connectionString == null)
{
throw new ArgumentNullException("connectionString");
}
EntityConnectionStringBuilder connectionBuilder = new EntityConnectionStringBuilder();
connectionBuilder.Metadata = "res://*/AlcatrazModel.csdl|res://*/AlcatrazModel.ssdl|res://*/AlcatrazModel.msl";
connectionBuilder.Provider = "System.Data.SqlClient";
connectionBuilder.ProviderConnectionString = connectionString;
_connectionString = connectionBuilder.ToString();
}
public IQueryable<Inmate> GetAllInmates()
{
AlcatrazEntities ents = new AlcatrazEntities(_connectionString);
return ents.Inmates;
}
}
Dans l'interface utilisateur Web:
IInmateRepository inmateRepo = new InmateRepository(@"data source=MATTHEW-PC\SQLEXPRESS;initial catalog=Alcatraz;integrated security=True;");
List<Inmate> deathRowInmates = inmateRepo.GetAllInmates().Where(i => i.OnDeathRow).ToList();
J'ai quelques questions connexes sur cette conception.
Cette conception a-t-elle même un sens en termes de capacités Entity Frameworks? J'ai entendu dire que le cadre Entity utilise déjà le modèle d'unité de travail, est-ce que j'ajoute simplement une autre couche d'abstrait inutilement?
Je ne veux pas que mon interface Web communique directement avec Entity Framework (ou même le référence d'ailleurs), je veux que tous les accès à la base de données passent par la couche métier, car à l'avenir, j'aurai plusieurs projets utilisant la même couche métier (service Web, application Windows, etc.) et je veux qu'il soit facile à maintenir / à mettre à jour en ayant la logique métier dans une zone centrale. Est-ce une façon appropriée d'y parvenir?
La couche Business doit-elle même contenir des référentiels, ou doit-elle être contenue dans la couche Access? Si leur emplacement est correct, le passage d'une chaîne de connexion est-il une bonne dépendance à assumer?
Merci d'avoir pris le temps de lire!
DbContext
comme sa dépendance. Les classes affaires ont des référentiels comme dépendance. Pour l'injection de dépendance, je fais cela manuellement (donc je comprends ce qui se passe). La raison pour laquelle je veux pouvoir définir la chaîne de connexion sur leDbContext
est que j'utilise le partage de base de données, donc dans certains cas, j'ai besoin d'un framework d'entité pour se connecter à différentes bases de données (de la même structure). Je vous comprends bien?Quelques commentaires rapides. Personnellement, je ne passerais probablement pas de chaîne de connexion. Si j'essayais de créer des interfaces pour les référentiels et de simplement passer les interfaces? Demandez aux référentiels d'implémenter ou d'exposer une interface IOW.
De cette façon, il n'a pas besoin d'être une base de données qui implémente vos référentiels. ils pourraient être un cache en mémoire, ou quoi que ce soit. Peut-être que vous pourriez alors utiliser une sorte de cadre d'injection de dépendance pour les instancier même?
Donc, en réponse à certaines de vos questions:
Ce ne sont là que quelques réflexions.
la source