0

Zuerst muss ich sagen, ich weiß, dass sie eine sehr enge Frage ist, die ich auf stackoverflow fand, aber meine Frage ist ein wenig anders.Wie man einen DbCOntext im n-tier-Repository-Muster teilt. Asp .net mvc

Ich habe n-Tier-Anwendung in asp .net MVC, in denen ich habe:
A BOL Projekt (die EF-Klassen hat und DB-Objekt usw.),
BLL Projekt (die buiseness Logik),
als wir haben DAL Projekt (die Db Interaktion Logik hat, und es EF dbcontext von BOL verwendet).
Und ein Haupt mvc Projekt, die nun

usw. Controller und Ansichten ahs, wir verwenden Repository-Muster, haben wir viele Repositorys in BLL mit ihren Schnittstellen. Und auch wir haben viele Repositories in DAL, die ohne Schnittstellen sind, obwohl. Aber alle diese DAL-Repositories haben ein DbContext-Mitglied in ihnen, die in ihren Konstruktoren erstellt wird, so jedes DAL-Repository interagiert mit separaten Instanz von DbContext, die es erstellt hat.


Und in unserem mvc Projekt haben wir verwendete ninject BLL-Repositories in Controllern Konstrukteurs (scope in Anfrage) zu injizieren. Nun, das Problem wir konfrontiert ist, dass jedes BLL-Repository Referenzen auf eine oder mehrere DAL-Repositorys hat, und jedes dieser DAL-Repositorys verwenden ihre eigenen separaten DbCOntext. Das ist falsch und schlecht, deshalb suche ich nach der Möglichkeit, einen DbCOntext in allen DAL-Repositories pro Anfrage zu teilen (Egal wie viele BLL-Repositories Ninject in meinen Controller injiziert, stelle nur sicher, dass nur eine DbContext-Instanz erstellt und verwendet wird auf Anfrage). Und diesen Kontext nach jeder Anfrage entsorgen.

Eine Möglichkeit, die ich dachte war nicht DBcontext im Konstruktor von DAL-Repositories zu erstellen. Aber haben Sie einen Methodenaufruf (sagen Sie initiateDbContext), als auch fügen Sie diese Methode in BLL-Repositories hinzu, die nichts anderes tun, als die Smae-Methode ihrer Mitglieds-DAL-Repositories aufzurufen. Rufen Sie diese Methode für eine BLL-Repository im Controller-Konstruktor, und dann eine Methode zum Abrufen und Festlegen Db-Kontexte in allen anderen Repositorys aus dem ersten Repository. Aber ich weiß, das ist ein schlechter Ansatz, zuerst erstellen wir DbContext im Controller, der nur in DAL sein sollte, zweitens erstelle ich create, dbCOntext Methoden in DAL und in BLL Repositories, da ich DbCOntext übergeben muss BLL, die das an die DAL-Repositories weitergibt, mit denen es intern kommuniziert. Und das ist sehr schlecht.

Deshalb frage ich hier jedes gute Muster zu erreichen "EIN DBCONTEXT PRO ANFRAGE IN N-Tier mit Repositorie-Muster."

+1

Die zufällige Fettschrift von Wörtern macht Ihre Frage nicht wirklich lesbarer. – CodeCaster

+0

@CodeCaster Ich weiß, dass meine Frage nicht sehr sinnvoll ist, aber ich habe versucht, einige wichtige Punkte hervorzuheben, damit es leicht verständlich ist. Vielleicht kannst du etwas vorschlagen? –

Antwort

2

Basierend auf der Antwort von @atika i weiter gesucht und umgesetzt, was er vorgeschlagen (mit ninject/DI ganz Anwendung und nicht nur in einem Hauptprojekt von mvc) und das Problem gelöst, mich dieses Posting Antwort, um mehr Details und einige zusätzliche Probleme hinzuzufügen, die ich gegenüberstellte, und ich habe Zeit damit verbracht, weiter zu googeln, damit andere Zeit sparen könnten.


Idee ist es, Abhängigkeitsinjektion in der gesamten Lösung zu verwenden, egal wie viele Projekte/Ebenen Sie haben und egal, wie viele Repositories Sie haben.

So kommt die Frage auf den Punkt, dass wenn wir ninject oder andere DI für die Bindung alle Abhängigkeiten von allen Ebenen/Projekte verwenden möchten, verweisen wir auf alle diese Ebenen/Projekte in unsere mvc haben sollte Projekt, so dass wir die Abhängigkeiten in NinjectWebCommons binden können, aber dies wird den gesamten Zweck der n-Tier-Architektur töten. Wir wollen nicht tun, dass wir unsere Hierarchie wollen, dass diese zu erhalten, wie in meinem Fall
MainMVCProject-> BLL-> DLL-> DB
So für, ich einen sehr hilfreichen Artikel gefundenNinject with N-Tier MVC Application - Inject Object in Business Layer. (Ihr sind auch einige andere Ansätze, ist man ein Projekt nur für Bindungen zu machen, und fügen Sie den Einsatz, das Projekt alle Abhängigkeiten zu binden, aber das klingt wie über Engineering und Overkill)

Basierend auf dem die folgenden i hinzugefügt Klasse in meinem BLL-Tier/Projekt (nach der Installation von ninject in diesem Projekt und DAL-Projekt auch), die Bindungen für DLL-Klassen hat.

using BLL.Repositories; 
using BLL.RepositoryInterfaces; 
using Ninject.Modules; 
using Ninject.Web.Common; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using DAL; 
using BOL; 

namespace BLL 
{ 
    public class LayerBindings : NinjectModule 
    { 
     public override void Load() 
     {//add all references here like these 
      Bind<AdDb>().ToSelf().InRequestScope(); 
      Bind<db_Entities>().ToSelf().InRequestScope().WithConstructorArgument("ConnectionString", BOL.CommonFunctionsBOL.ConnectionString); 
     } 
    } 
} 

etwas Hilfe von howto-ninject-part-1-basics Artikel bekommen konnte ich viele Dinge mit ninject tun, und verwendet viele seiner Funktionen.

Jetzt können Sie sehen Ich habe die Bindungen von DLL-Projekt in dieser Klasse hinzugefügt, die im Haupt-MVC-Projekt nicht zugänglich waren. Jetzt muss ich diese Bindungen nur noch in main ninject laden. Jetzt , in NinjectWebCommons.cs Datei, habe ich folgende Zeilen: (. In RegisterServices Verfahren nach lokalen Bindungen und BLL-Objekte Bindungen)

//old bindings of BLL and local project.  
kernel.Bind<IUserRepository>().To<UserRepository>().InRequestScope(); 
//now here we bind other dependencies of DAL etc using class we added in BLL 
var modules = new List<INinjectModule> 
{ 
     new BLL.LayerBindings() 
}; 
kernel.Load(modules); 

Nachdem ich nur dies, ninject zu arbeiten begann in allen Projekten und ich habe gerade Konstruktor Injektion oder an einigen Stellen, Immobilien Injektionen und alles hat gut funktioniert.

PS1: Ich benutzte auch Eigenschaft Injektion * (i gelesen, dass diese nicht zu verwenden Eigenschaft Injektionen empfohlen wird, verwenden sie nur, wo Sie Konstruktor Injektionen verwenden kann nicht.) * Für private Eigenschaften und sie hatten die Lage versetzt werden mit kernel.Settings.InjectNonPublic = true; Zeile in "CreateKernel" -Methode vor dem Zurückgeben des Kernels.
Jetzt ist mein Eigentum Einspritzung auch für private Eigenschaften arbeiten, wie folgt aus:

[Ninject.Inject] 
private SomeDALObject db { get; set; } 

PS2: Ich installierte auch ninject.web.webapi nugget paket für ninject mit webapis zu arbeiten, und auch gefunden diese linie, um ein objekt überall von ninjec t. () Ich weiß nicht, ob dies ein guter Weg ist oder nicht, aber es gibt eine vollständig erstellt Objekt, das ich früher als. wenn jemand kann mir klären oder korrigieren, wenn dies mit Recht oder nicht, das wird groß sein.)

((TypeOfObjectYouWant)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(TypeOfObjectYouWant))).DoSomething(); 

ich hoffe, das wie mich einige Leute für die richtige Führung der Suche helfen könnte auf dieses Problem.

+0

Dank @Zia machte es für zukünftige Besucher wirklich einfach. –

-1
You can write one BaseRepository and implement BaseRepository in all  repository classes. 

public class BaseRepository 
    { 
     public StudentEntities dbStudentEntity; 

     public BaseRepository() 
     { 
      dbStudentEntity = new StudentEntities(); 
     } 
    } 

DataRepository : 

public class CurrencyData : BaseRepository,ICurrencyData 
    { 
     public List<Models.Currency> GetCurrencyList() 
     { 
      var objCurrencies = dbStudentEntity.Currencies.ToList(); 
      List<Models.Currency> currencyList = new  List<Models.Currency>(); 

      foreach (var item in objCurrencies) 
      { 
       var model = new Models.Currency { CurrencyId =  item.CurrencyId, Currency1 = item.Currency1,Code = item.Code,Symbol =  item.Symbol,Country = item.Country }; 
       currencyList.Add(model); 
      } 
      return currencyList; 
     } 

    } 
+0

wird es nicht immer der Fall sein, dass jedes Repository eine neue Instanz des Basisrepositorys erhält, d. H. Jedes Repository wird wieder einen anderen Kontext haben? Weil jedes Repository von BaseRepository erbt? –

+0

@Dilip N Dies ist nicht das, was OP angefordert hat, bitte überdenken Sie Ihre Antwort – Eldho

2

Wenn Sie Dependency Injection verwenden, sollten Sie es den ganzen Weg nutzen, nicht nur in den Controller.
Das bedeutet, der DBContext sollte in die Repositories eingefügt werden, und Ninject sollte so konfiguriert werden, dass er Ihren DBContext mit jeder Lebenszeit auffordert.

+0

Macht Sinn, es bedeutet, ich sollte Ninject in meinem DAL-Projekt einschließen, und alle meine Repositorys sollten injiziert werden die Abhängigkeiten, die sie benötigen, BLL-Repositories sollten DAL erhalten injiziert, und DAL-Repositorys sollten DbCOntext erhalten, der von Ninject in sie injiziert wird. Dies macht durchaus Sinn, aber ich habe nie Ninject in dieser Art von geschichteter Architektur verwendet. Was sollte ich googeln um ein paar Infos dazu zu bekommen? Ich meine, was ist die Terminologie dafür. –

+1

Der erste Treffer für "ninject multiple layers" sieht wie ein guter Ausgangspunkt aus. Ich bin mit Ninject nicht sehr vertraut, aber ich sehe, dass es Module unterstützt. Das ist es, was ich mit Autofac benutze, jede Ebene hat ihr eigenes Modul und es wird von der darüber liegenden Ebene geladen. Macht die Schichtentrennung sehr einfach zu implementieren. –

+0

Okay, ich untersuche es, und ich sollte sagen, ich bin neu dazu, also könnte ich im Falle von weiteren Verwirrungen aufholen. Vielen Dank für Ihre Antwort. Ich werde akzeptiert, sobald mein Problem gelöst ist. –