├── .gitignore
├── ChinookASPNETCoreAPINTier
├── Chinook.API
│ ├── Chinook.API.csproj
│ ├── Configurations
│ │ ├── AppSettings.cs
│ │ ├── ConfigureAppSettings.cs
│ │ ├── ConfigureConnections.cs
│ │ └── ServicesConfiguration.cs
│ ├── Controllers
│ │ ├── AlbumController.cs
│ │ ├── ArtistController.cs
│ │ ├── CustomerController.cs
│ │ ├── EmployeeController.cs
│ │ ├── GenreController.cs
│ │ ├── HomeController.cs
│ │ ├── InvoiceController.cs
│ │ ├── InvoiceLineController.cs
│ │ ├── MediaTypeController.cs
│ │ ├── PlaylistController.cs
│ │ └── TrackController.cs
│ ├── Program.cs
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── Chinook.DataEFCore
│ ├── Chinook.DataEFCore.csproj
│ ├── ChinookContext.cs
│ ├── Configurations
│ │ ├── AlbumConfiguration.cs
│ │ ├── ArtistConfiguration.cs
│ │ ├── CustomerConfiguration.cs
│ │ ├── EmployeeConfiguration.cs
│ │ ├── GenreConfiguration.cs
│ │ ├── InvoiceConfiguration.cs
│ │ ├── InvoiceLineConfiguration.cs
│ │ ├── MediaTypeConfiguration.cs
│ │ ├── PlaylistConfiguration.cs
│ │ ├── PlaylistTrackConfiguration.cs
│ │ └── TrackConfiguration.cs
│ └── Repositories
│ │ ├── AlbumRepository.cs
│ │ ├── ArtistRepository.cs
│ │ ├── CustomerRepository.cs
│ │ ├── EmployeeRepository.cs
│ │ ├── GenreRepository.cs
│ │ ├── InvoiceLineRepository.cs
│ │ ├── InvoiceRepository.cs
│ │ ├── MediaTypeRepository.cs
│ │ ├── PlaylistRepository.cs
│ │ ├── PlaylistTrackRepository.cs
│ │ └── TrackRepository.cs
├── Chinook.DataEFCoreCmpldQry
│ ├── Chinook.DataEFCoreCmpldQry.csproj
│ ├── ChinookContext.cs
│ ├── Configurations
│ │ ├── AlbumConfiguration.cs
│ │ ├── ArtistConfiguration.cs
│ │ ├── CustomerConfiguration.cs
│ │ ├── EmployeeConfiguration.cs
│ │ ├── GenreConfiguration.cs
│ │ ├── InvoiceConfiguration.cs
│ │ ├── InvoiceLineConfiguration.cs
│ │ ├── MediaTypeConfiguration.cs
│ │ ├── PlaylistConfiguration.cs
│ │ ├── PlaylistTrackConfiguration.cs
│ │ └── TrackConfiguration.cs
│ └── Repositories
│ │ ├── AlbumRepository.cs
│ │ ├── ArtistRepository.cs
│ │ ├── CustomerRepository.cs
│ │ ├── EmployeeRepository.cs
│ │ ├── GenreRepository.cs
│ │ ├── InvoiceLineRepository.cs
│ │ ├── InvoiceRepository.cs
│ │ ├── MediaTypeRepository.cs
│ │ ├── PlaylistRepository.cs
│ │ ├── PlaylistTrackRepository.cs
│ │ └── TrackRepository.cs
├── Chinook.Domain
│ ├── ApiModels
│ │ ├── AlbumApiModel.cs
│ │ ├── ArtistApiModel.cs
│ │ ├── CustomerApiModel.cs
│ │ ├── EmployeeApiModel.cs
│ │ ├── GenreApiModel.cs
│ │ ├── InvoiceApiModel.cs
│ │ ├── InvoiceLineApiModel.cs
│ │ ├── MediaTypeApiModel.cs
│ │ ├── PlaylistApiModel.cs
│ │ ├── PlaylistTrackApiModel.cs
│ │ └── TrackApiModel.cs
│ ├── Chinook.Domain.csproj
│ ├── Converters
│ │ └── IConvertModel.cs
│ ├── Entities
│ │ ├── Album.cs
│ │ ├── Artist.cs
│ │ ├── Customer.cs
│ │ ├── Employee.cs
│ │ ├── Genre.cs
│ │ ├── Invoice.cs
│ │ ├── InvoiceLine.cs
│ │ ├── MediaType.cs
│ │ ├── Playlist.cs
│ │ ├── PlaylistTrack.cs
│ │ └── Track.cs
│ ├── Extensions
│ │ └── ConvertExtensions.cs
│ ├── Repositories
│ │ ├── IAlbumRepository.cs
│ │ ├── IArtistRepository.cs
│ │ ├── ICustomerRepository.cs
│ │ ├── IEmployeeRepository.cs
│ │ ├── IGenreRepository.cs
│ │ ├── IInvoiceLineRepository.cs
│ │ ├── IInvoiceRepository.cs
│ │ ├── IMediaTypeRepository.cs
│ │ ├── IPlaylistRepository.cs
│ │ ├── IPlaylistTrackRepository.cs
│ │ └── ITrackRepository.cs
│ └── Supervisor
│ │ ├── ChinookSupervisor.cs
│ │ ├── ChinookSupervisorAlbum.cs
│ │ ├── ChinookSupervisorArtist.cs
│ │ ├── ChinookSupervisorCustomer.cs
│ │ ├── ChinookSupervisorEmployee.cs
│ │ ├── ChinookSupervisorGenre.cs
│ │ ├── ChinookSupervisorInvoice.cs
│ │ ├── ChinookSupervisorInvoiceLine.cs
│ │ ├── ChinookSupervisorMediaType.cs
│ │ ├── ChinookSupervisorPlaylist.cs
│ │ ├── ChinookSupervisorPlaylistTrack.cs
│ │ ├── ChinookSupervisorTrack.cs
│ │ └── IChinookSupervisor.cs
├── Chinook.IntegrationTest
│ ├── API
│ │ ├── AlbumAPIAlbaTest.cs
│ │ ├── AlbumAPITest.cs
│ │ ├── ArtistAPITest.cs
│ │ ├── CustomerAPITest.cs
│ │ ├── EmployeeAPITest.cs
│ │ ├── GenreAPITest.cs
│ │ ├── InvoiceAPITest.cs
│ │ ├── InvoiceLineAPITest.cs
│ │ ├── MediaTypeAPITest.cs
│ │ ├── PlaylistAPITest.cs
│ │ └── TrackAPITest.cs
│ ├── AlbumAddOne.http
│ ├── AlbumDeleteOne.http
│ ├── AlbumGetAll.http
│ ├── AlbumGetOne.http
│ ├── AlbumUpdateOne.http
│ └── Chinook.IntegrationTest.csproj
├── Chinook.MSUnitTest
│ ├── AlbumRepositoryTest.cs
│ └── Chinook.MSUnitTest.csproj
├── Chinook.MockData
│ ├── Chinook.MockData.csproj
│ ├── ObjectExtensions.cs
│ └── Repositories
│ │ ├── AlbumRepository.cs
│ │ ├── ArtistRepository.cs
│ │ ├── CustomerRepository.cs
│ │ ├── EmployeeRepository.cs
│ │ ├── GenreRepository.cs
│ │ ├── InvoiceLineRepository.cs
│ │ ├── InvoiceRepository.cs
│ │ ├── MediaTypeRepository.cs
│ │ ├── PlaylistRepository.cs
│ │ ├── PlaylistTrackRepository.cs
│ │ └── TrackRepository.cs
├── Chinook.UnitTest
│ ├── Chinook.UnitTest.csproj
│ ├── Repository
│ │ ├── AlbumRepositoryTest.cs
│ │ ├── ArtistRepositoryTest.cs
│ │ ├── CustomerRepositoryTest.cs
│ │ ├── EmployeeRepositoryTest.cs
│ │ ├── GenreRepositoryTest.cs
│ │ ├── InvoiceLineRepositoryTest.cs
│ │ ├── InvoiceRepositoryTest.cs
│ │ ├── MediaTypeRepositoryTest.cs
│ │ ├── PlayListRepositoryTest.cs
│ │ ├── PlayListTrackRepositoryTest.cs
│ │ └── TrackRepositoryTest.cs
│ └── Supervisor
│ │ ├── AlbumSupervisorTest.cs
│ │ ├── ArtistSupervisorTest.cs
│ │ ├── CustomerSupervisorTest.cs
│ │ ├── EmployeeSupervisorTest.cs
│ │ ├── GenreSupervisorTest.cs
│ │ ├── InvoiceLineSupervisorTest.cs
│ │ ├── InvoiceSupervisorTest.cs
│ │ ├── MediaTypeSupervisorTest.cs
│ │ ├── PlayListSupervisorTest.cs
│ │ ├── PlayListTrackSupervisorTest.cs
│ │ └── TrackSupervisorTest.cs
└── ChinookASPNETCoreAPINTier.sln
├── Developing ASP.NET Core 2.2 Web APIs for your Web and Mobile Apps-NTier.pptx
├── LICENSE
├── README.md
└── script_webapi.txt
/ChinookASPNETCoreAPINTier/Chinook.API/Chinook.API.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp2.2
4 | latest
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Always
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Configurations/AppSettings.cs:
--------------------------------------------------------------------------------
1 | namespace Chinook.API.Configurations
2 | {
3 | public abstract class AppSettings
4 | {
5 |
6 | }
7 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Configurations/ConfigureAppSettings.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace Chinook.API.Configurations
5 | {
6 | public static class ConfigureAppSettings
7 | {
8 | public static IServiceCollection AddAppSettings(this IServiceCollection services, IConfiguration configuration)
9 | {
10 | services.Configure(_ => configuration.GetSection("AppSettings").Bind(_));
11 |
12 | return services;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Configurations/ConfigureConnections.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using Microsoft.EntityFrameworkCore;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.DependencyInjection;
6 | using Chinook.DataEFCoreCmpldQry;
7 |
8 | namespace Chinook.API.Configurations
9 | {
10 | public static class ConfigureConnections
11 | {
12 | public static IServiceCollection AddConnectionProvider(this IServiceCollection services,
13 | IConfiguration configuration)
14 | {
15 | var connection = String.Empty;
16 |
17 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
18 | {
19 | connection = configuration.GetConnectionString("ChinookDbWindows") ??
20 | "Server=.;Database=Chinook;Trusted_Connection=True;Application Name=ChinookASPNETCoreAPINTier";
21 | }
22 | else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
23 | {
24 | connection = configuration.GetConnectionString("ChinookDbDocker") ??
25 | "Server=localhost,1433;Database=Chinook;User=sa;Password=Pa55w0rd;Trusted_Connection=False;Application Name=ChinookASPNETCoreAPINTier";
26 | }
27 |
28 | services.AddDbContextPool(options => options.UseSqlServer(connection));
29 |
30 | return services;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Configurations/ServicesConfiguration.cs:
--------------------------------------------------------------------------------
1 | using Chinook.DataEFCoreCmpldQry.Repositories;
2 | using Chinook.Domain.Repositories;
3 | using Chinook.Domain.Supervisor;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Logging;
6 | using Newtonsoft.Json;
7 |
8 | namespace Chinook.API.Configurations
9 | {
10 | public static class ServicesConfiguration
11 | {
12 | public static IServiceCollection ConfigureRepositories(this IServiceCollection services)
13 | {
14 | services.AddScoped()
15 | .AddScoped()
16 | .AddScoped()
17 | .AddScoped()
18 | .AddScoped()
19 | .AddScoped()
20 | .AddScoped()
21 | .AddScoped()
22 | .AddScoped()
23 | .AddScoped();
24 |
25 | return services;
26 | }
27 |
28 | public static IServiceCollection ConfigureSupervisor(this IServiceCollection services)
29 | {
30 | services.AddScoped();
31 |
32 | return services;
33 | }
34 |
35 | public static IServiceCollection AddMiddleware(this IServiceCollection services)
36 | {
37 | services.AddMvc().AddJsonOptions(options =>
38 | {
39 | options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
40 | });
41 |
42 | return services;
43 | }
44 |
45 | public static IServiceCollection AddLogging(this IServiceCollection services)
46 | {
47 | services.AddLogging(builder => builder
48 | .AddConsole()
49 | .AddFilter(level => level >= LogLevel.Information)
50 | );
51 |
52 | return services;
53 | }
54 |
55 | public static IServiceCollection AddCaching(this IServiceCollection services)
56 | {
57 | services.AddMemoryCache();
58 | services.AddResponseCaching();
59 |
60 | return services;
61 | }
62 |
63 | public static IServiceCollection AddCORS(this IServiceCollection services)
64 | {
65 | services.AddCors(options =>
66 | {
67 | options.AddPolicy("CorsPolicy",
68 | builder => builder.WithOrigins("http://example.com")
69 | .AllowAnyMethod()
70 | .AllowAnyHeader()
71 | .AllowCredentials());
72 | });
73 |
74 | return services;
75 | }
76 |
77 |
78 | }
79 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Chinook.API.Controllers
5 | {
6 | public class HomeController : Controller
7 | {
8 | [HttpGet]
9 | [ApiExplorerSettings(IgnoreApi = true)]
10 | public IActionResult Index()
11 | {
12 | try
13 | {
14 | var uri = new Uri("/swagger", UriKind.Relative);
15 | return Redirect(uri.ToString());
16 | }
17 | catch (Exception ex)
18 | {
19 | return StatusCode(500, ex);
20 | }
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 |
4 | namespace Chinook.API
5 | {
6 | public class Program
7 | {
8 | public static void Main(string[] args) => BuildWebHost(args).Run();
9 |
10 | private static IWebHost BuildWebHost(string[] args) =>
11 | WebHost.CreateDefaultBuilder(args)
12 | .UseStartup()
13 | .Build();
14 | }
15 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Logging;
6 | using Chinook.API.Configurations;
7 | using Microsoft.AspNetCore.Mvc;
8 | using Swashbuckle.AspNetCore.Swagger;
9 |
10 | namespace Chinook.API
11 | {
12 | public class Startup
13 | {
14 | private IConfiguration Configuration { get; }
15 |
16 | public Startup(IConfiguration configuration)
17 | {
18 | Configuration = configuration;
19 | }
20 |
21 | // This method gets called by the runtime. Use this method to add services to the container.
22 | public void ConfigureServices(IServiceCollection services)
23 | {
24 | services.Configure(options =>
25 | {
26 | options.MaxValidationDepth = 2;
27 | });
28 |
29 | services.AddMvc()
30 | .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
31 |
32 | services.ConfigureRepositories()
33 | .ConfigureSupervisor()
34 | .AddMiddleware()
35 | .AddConnectionProvider(Configuration)
36 | .AddAppSettings(Configuration)
37 | .AddCaching()
38 | .AddCORS();
39 |
40 | services.AddSwaggerGen(s => s.SwaggerDoc("v1", new Info
41 | {
42 | Title = "Chinook API",
43 | Description = "Chinook Music Store API"
44 | }));
45 | }
46 |
47 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
48 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
49 | {
50 | if (env.IsDevelopment())
51 | {
52 | app.UseDeveloperExceptionPage();
53 | }
54 | else
55 | {
56 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
57 | app.UseHsts();
58 | }
59 |
60 | app.UseCors("CorsPolicy");
61 | app.UseStaticFiles();
62 | app.UseHttpsRedirection();
63 | app.UseMvc(
64 | routes => routes.MapRoute(
65 | "default",
66 | "{controller=Home}/{action=Index}/{id?}"));
67 | app.UseSwagger();
68 | app.UseSwaggerUI(s => s.SwaggerEndpoint("/swagger/v1/swagger.json", "v1 docs"));
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Debug",
6 | "System": "Information",
7 | "Microsoft": "Information"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.API/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConnectionStrings": {
3 | "ChinookDbWindows": "Server=.;Database=Chinook;Trusted_Connection=True;Application Name=ChinookASPNETCoreAPINTier",
4 | "ChinookDbDocker": "Server=localhost,1433;Database=Chinook;User=sa;Password=P@ssw0rd1;Trusted_Connection=False;Application Name=ChinookASPNETCoreAPINTier"
5 | },
6 | "Logging": {
7 | "IncludeScopes": false,
8 | "Debug": {
9 | "LogLevel": {
10 | "Default": "Warning"
11 | }
12 | },
13 | "Console": {
14 | "LogLevel": {
15 | "Default": "Warning"
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.DataEFCore/Chinook.DataEFCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp2.2
4 | latest
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ChinookASPNETCoreAPINTier/Chinook.DataEFCore/ChinookContext.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using Microsoft.EntityFrameworkCore;
3 | using Chinook.DataEFCore.Configurations;
4 | using Chinook.Domain.Entities;
5 |
6 | namespace Chinook.DataEFCore
7 | {
8 | public class ChinookContext : DbContext
9 | {
10 | public virtual DbSet Album { get; set; }
11 | public virtual DbSet Artist { get; set; }
12 | public virtual DbSet Customer { get; set; }
13 | public virtual DbSet Employee { get; set; }
14 | public virtual DbSet Genre { get; set; }
15 | public virtual DbSet Invoice { get; set; }
16 | public virtual DbSet InvoiceLine { get; set; }
17 | public virtual DbSet MediaType { get; set; }
18 | public virtual DbSet Playlist { get; set; }
19 | public virtual DbSet PlaylistTrack { get; set; }
20 | public virtual DbSet