Ok, what you do is common, but some nuances that needs to be adjusted here and there.
You're using an N Tier for your backend ( Presentation Layer, BL and DAL ) And using a Angular as a Frontend Client.
First off all let's start with your Angular2 project. Is see that you added 'controllers' to it, which isn't necessary. Your angular App should have this flow:
User <-> HTML/Component <-> Service.
The user interacts with the html which are link to a component. Your components communicate with your services.
A component is used for as a 'View' class, and a service is used to communicate with the backend. When your component needs data, it will ask it to the service, which will make a cal to the entry points of your backend.
So now the backend.
The entry point of you backend is your Presentation Layer (PL), in your case this will be the controllers of your WEB API. As I already said, controllers should not be server in the client, but in the API of the backend. Those are actually the endpoints you communicate with trough your Angular2 Services.
We now have this:
Angular Frontend(HTML/Component <-> Service <->) <-> Backend(PL/Controller)
Often you want to have a layer that communicates with data, aka the Data Access Layer( DAL ). This will have the responsibility to communicate with your database. It will be responsible to persist your data, and should only be aware of CRUD(Create, Reade, Update, Delete) operations with your database.
Now There is also the business layer ( BL ) which settles in between your PL and DAL. As your PL is an endpoint for your frontend, and your DAL is your communication point with your DB, you will need a layer that handles all the business logic that happens with your data. This is done in the BL.
So the whole chain is like this:
ANGULAR(HTML/COMPONENT <-> SERVICE) <-> BACKEND(PL <-> BL <-> DAL) <-> DB.
Let's write an example.
You've got a product component in Angular2 which show a list of products.
Your component in Angular will have a variable products. When the component needs to be loaded, it will ask to the ProductService in angular2 to make a call ( HTTP ) to the ProductController from your WEB API in your backend.
The ProductController will have a instance of a ProductService from your BL ( not a product service from angular, same name convention, but different things !).
In the BL's ProductService, you'll handle all the logic you want to with the data. This service has an instance of a ProductRepository ( a class from the DAL which handles the CRUD operations with the database ) and will use the correct method to request the list of products from the DB.
The DAL will have a connection to the Database and will provide the BL with the data they ask. If you want to use an ORM ( like Entity Framework), you'll have to init this in the DAL.
Now as a good practice, to add some abstraction and have a Loose Coupling between your PL Controllers, BL Services and DAL Repositories, you'll want to make an interface for the last 2.
That means that ProductService will be an implementation of IProductService, and ProductRepository and implementation of IProductRepository.
The Controller in PL will have an instance of the service interface instead of the implementation of it, same for the repository in your service. By doing this you'll have more detached and independent layers.
Sorry for the BIG post, but it's a complicated subject.
EDIT:
I'll add some code snippets of the implementation of the backend with interfaces:
Controller
[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);
}
}
Service & Interface
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 & Interface
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();
}
}
The snippets are very naive, it's just to demonstrate the concept.