Ok, quello che fai è comune, ma alcune sfumature che devono essere regolate qua e là.
Stai utilizzando un livello N per il tuo back-end (Presentation Layer, BL e DAL) e utilizza un client angolare come frontend.
Per prima cosa iniziamo con il tuo progetto Angular2. Si vede che hai aggiunto 'controller' ad esso, che non è necessario. La tua app angolare dovrebbe avere questo flusso:
Utente < - > HTML / Componente < - > Servizio.
L'utente interagisce con l'html che sono link a un componente. I tuoi componenti comunicano con i tuoi servizi.
Un componente viene utilizzato come classe "Visualizza" e un servizio viene utilizzato per comunicare con il back-end. Quando il tuo componente ha bisogno di dati, lo chiederà al servizio, il che renderà un punto di accesso ai punti di ingresso del tuo back-end.
Quindi ora il back-end.
Il punto di ingresso del tuo back-end è il tuo Presentation Layer (PL), nel tuo caso questo sarà il controller della tua WEB API. Come ho già detto, i controller non dovrebbero essere server nel client, ma nell'API del back-end. Questi sono in realtà gli endpoint che comunichi con i servizi Angular2.
Ora abbiamo questo:
Frontend angolare (HTML / Componente < - > Servizio < - >) < - > Backend (PL / Controller)
Spesso vuoi avere un livello che comunica con i dati, ovvero il Data Access Layer (DAL). Questo avrà la responsabilità di comunicare con il tuo database. Sarà responsabile per mantenere i tuoi dati, e dovrebbe solo essere a conoscenza delle operazioni CRUD (Crea, Leggi, Aggiorna, Elimina) con il tuo database.
Ora c'è anche il livello aziendale (BL) che si stabilisce tra PL e DAL. Poiché il PL è un endpoint per il frontend e il tuo DAL è il tuo punto di comunicazione con il tuo DB, avrai bisogno di un livello che gestisca tutta la logica aziendale che si verifica con i tuoi dati. Questo è fatto nel BL.
Quindi l'intera catena è così:
ANGOLARE (HTML / COMPONENT < - > SERVICE) < - > BACKEND (PL < - > BL < - > DAL) < - > DB.
Scriviamo un esempio.
Hai un componente del prodotto in Angular2 che mostra un elenco di prodotti.
Il tuo componente in Angular avrà prodotti variabili. Quando il componente deve essere caricato, chiederà al ProductService in angular2 di effettuare una chiamata (HTTP) al ProductController dalla tua API WEB nel back-end.
Il ProductController avrà un'istanza di un ProductService dal tuo BL (non un servizio prodotto da una convenzione angolare, con lo stesso nome, ma cose diverse!).
Nel ProductService del BL, gestirai tutta la logica che desideri con i dati. Questo servizio ha un'istanza di ProductRepository (una classe del DAL che gestisce le operazioni CRUD con il database) e utilizzerà il metodo corretto per richiedere l'elenco di prodotti dal DB.
Il DAL avrà una connessione al Database e fornirà al BL i dati che chiedono. Se si desidera utilizzare un ORM (come Entity Framework), è necessario iniziarlo nel DAL.
Ora come buona pratica, per aggiungere un po 'di astrazione e avere un accoppiamento libero tra i tuoi controller PL, i servizi BL e i repository DAL, ti consigliamo di creare un'interfaccia per gli ultimi 2.
Ciò significa che ProductService sarà un'implementazione di IProductService e ProductRepository e implementazione di IProductRepository.
Il Controller in PL avrà un'istanza dell'interfaccia di servizio invece dell'implementazione di essa, lo stesso per il repository nel tuo servizio. In questo modo avrai più livelli separati e indipendenti.
Ci scusiamo per il post GRANDE, ma è un argomento complicato.
EDIT:
Aggiungerò alcuni frammenti di codice dell'implementazione del back-end con le interfacce:
Regolatore
[Route('api/[controller]')]
public class ProductController : Controller{
private IProductService _productService = new ProductService();
public IActionResult GetProducts(){
var products = _productService.GetAll();
if(products = null) return BadRequest(products);
return Ok(products);
}
}
Servizio e amp; Interfaccia
public interface IProductService{
List<Product> GetAll();
}
public class ProductService : IProductService{
private readonly IProductRepository _productRepository;
public ProductService(){
_productRepository = new ProductRepository();
}
public List<Product> GetAll(){
var products = _productRepository.ReadAll();
//Do some logic with products
//..
return products;
}
}
Repository & Interfaccia
public interface IProductRepository{
List<Product> ReadAll();
}
public class ProductRepository : IProductRepository{
private DbContext _ctx;
public ProductService(){
_ctx = new DbContext();
}
public List<Product> ReadAll(){
return _ctx.Products.FindAll();
}
}
I frammenti sono molto ingenui, è solo per dimostrare il concetto.