clean-architecture-master\.vs\Movies\DesignTimeBuild\.dtbcache.v2
clean-architecture-master\.vs\Movies\v17\.futdcache.v2
clean-architecture-master\.vs\Movies\v17\.suo
clean-architecture-master\.vs\Movies\v17\DocumentLayout.json
{
"Version": 1,
"WorkspaceRootPath": "D:\\Code\\clean-architecture-master\\",
"Documents": [],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
}
]
}
]
}
]
}
clean-architecture-master\.vs\ProjectEvaluation\movies.projects.v9.bin
clean-architecture-master\.vs\ProjectEvaluation\movies.strings.v9.bin
clean-architecture-master\Movies.API\appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
clean-architecture-master\Movies.API\appsettings.json
{
"ConnectionStrings": {
"MovieConnection": "Data Source=localhost;Initial Catalog=cqrsdb;User ID=sa;Password=xxxx..;Trust Server Certificate=True"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
clean-architecture-master\Movies.API\Dockerfile
clean-architecture-master\Movies.API\Movies.API.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Movies.Application\Movies.Application.csproj" />
<ProjectReference Include="..\Movies.Infrastructure\Movies.Infrastructure.csproj" />
<ProjectReference Include="..\Movies.Jobs\Movies.Jobs.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" />
<PackageReference Include="Quartz" Version="3.8.1" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.8.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>
clean-architecture-master\Movies.API\Program.cs
using Movies.Infrastructure.Data;
namespace Movies.API
{
public class Program
{
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await CreateAndSeedDb(host);
host.Run();
}
private static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
private static async Task CreateAndSeedDb(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
try
{
var moviesContext = services.GetRequiredService<MovieContext>();
await MovieContextSeed.SeedAsync(moviesContext, loggerFactory);
}
catch (Exception ex)
{
var logger = loggerFactory.CreateLogger<Program>();
logger.LogError($"Exception occured in API: {ex.Message}");
}
}
}
}
}
clean-architecture-master\Movies.API\Startup.cs
using System.Reflection;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using Movies.Application.Handlers;
using Movies.Core.Repositories;
using Movies.Core.Repositories.Base;
using Movies.Infrastructure.Data;
using Movies.Infrastructure.Repositories;
using Movies.Infrastructure.Repositories.Base;
using Movies.Jobs;
using Quartz;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Movies.API;
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
});
services.AddDbContext<MovieContext>(
m => m.UseSqlServer(Configuration.GetConnectionString("MovieConnection")),
ServiceLifetime.Singleton
);
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Movie API", Version = "v1" });
c.SwaggerDoc("v2", new OpenApiInfo { Title = "Movie API", Version = "v2" });
c.DocInclusionPredicate(
(version, apiDesc) =>
{
var versions = apiDesc
.CustomAttributes()
.OfType<ApiVersionAttribute>()
.SelectMany(attr => attr.Versions);
return versions.Any(v => $"v{v.ToString()}" == version);
}
);
});
services.AddAutoMapper(typeof(Startup));
services.AddMediatR(typeof(CreateMovieCommandHandler).GetTypeInfo().Assembly);
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddTransient<IMovieRepository, MovieRepository>();
// 添加 Quartz 服务
services.AddQuartz(q =>
{
// 配置定时任务
var jobKey = new JobKey("PickingAndShippingJob");
q.AddJob<PickingAndShippingJob>(opts => opts.WithIdentity(jobKey));
q.AddTrigger(opts =>
opts.ForJob(jobKey)
.WithIdentity("PickingAndShippingJob-trigger")
.WithCronSchedule("0/5 * * * * ?")
); // 每5秒执行一次
});
services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Movie API V1");
c.SwaggerEndpoint("/swagger/v2/swagger.json", "Movie API V2");
});
// 将swagger重定向到根目录
app.Use(
async (context, next) =>
{
if (context.Request.Path == "/")
{
context.Response.Redirect("/swagger");
return;
}
await next();
}
);
}
}
clean-architecture-master\Movies.API\Controllers\ApiController.cs
using Microsoft.AspNetCore.Mvc;
namespace Movies.API.Controllers;
[ApiVersion("1")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class ApiController: ControllerBase
{
}
clean-architecture-master\Movies.API\Controllers\V1\MovieController.cs
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Movies.Application.Commands;
using Movies.Application.Queries;
using Movies.Application.Responses;
namespace Movies.API.Controllers;
[ApiVersion("1")]
[Route("api/v{version:apiVersion}/movie")]
[ApiController]
public class MovieController : ControllerBase
{
private readonly IMediator _mediator;
public MovieController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<MovieResponse>>> GetMovies()
{
var query = new GetMoviesQuery();
var result = await _mediator.Send(query);
return Ok(result);
}
[HttpGet("directorName/{directorName}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<MovieResponse>>> GetMoviesByDirectorName(string directorName)
{
var query = new GetMoviesByDirectorNameQuery(directorName);
var result = await _mediator.Send(query);
return Ok(result);
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<MovieResponse>> CreateMovie([FromBody] CreateMovieCommand command)
{
var result = await _mediator.Send(command);
return Ok(result);
}
}
clean-architecture-master\Movies.API\Controllers\V2\MovieV2Controller.cs
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Movies.Application.Commands;
using Movies.Application.Queries;
using Movies.Application.Responses;
namespace Movies.API.Controllers;
[ApiVersion("2")]
[Route("api/v{version:apiVersion}/movie")]
[ApiController]
public class MovieVIIController : ControllerBase
{
private readonly IMediator _mediator;
public MovieVIIController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("all")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<MovieResponse>>> GetMovies()
{
var query = new GetMoviesQuery();
var result = await _mediator.Send(query);
return Ok(result);
}
// 添加新的或修改的操作方法
[HttpGet("new-feature")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<string> NewFeature()
{
return Ok("This is a new feature in version 2");
}
}
clean-architecture-master\Movies.API\Properties\launchSettings.json
{
"profiles": {
"Movies.API": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:11517;http://localhost:11518"
}
}
}
clean-architecture-master\Movies.Application\Movies.Application.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Movies.Core\Movies.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="FluentValidation" Version="11.5.1" />
<PackageReference Include="MediatR" Version="11.0.0" />
</ItemGroup>
</Project>
clean-architecture-master\Movies.Application\Commands\CreateMovieCommand.cs
using MediatR;
using Movies.Application.Responses;
namespace Movies.Application.Commands;
public class CreateMovieCommand : IRequest<MovieResponse>
{
public string MovieName { get; set; }
public string DirectorName { get; set; }
public string ReleaseYear { get; set; }
}
clean-architecture-master\Movies.Application\Handlers\CreateMovieCommandHandler.cs
using MediatR;
using Movies.Application.Commands;
using Movies.Application.Mappers;
using Movies.Application.Responses;
using Movies.Core.Entities;
using Movies.Core.Repositories;
namespace Movies.Application.Handlers;
public class CreateMovieCommandHandler: IRequestHandler<CreateMovieCommand, MovieResponse>
{
private readonly IMovieRepository _movieRepository;
public CreateMovieCommandHandler(IMovieRepository movieRepository)
{
_movieRepository = movieRepository;
}
public async Task<MovieResponse> Handle(CreateMovieCommand request, CancellationToken cancellationToken)
{
var movieEntity = MovieMapper.Mapper.Map<Movie>(request);
if (movieEntity is null)
{
throw new ApplicationException("There is an issue with mapping...");
}
var newMovie = await _movieRepository.AddAsync(movieEntity);
var movieResponse = MovieMapper.Mapper.Map<MovieResponse>(newMovie);
return movieResponse;
}
}
clean-architecture-master\Movies.Application\Handlers\GetMoviesByDirectorNameHandler.cs
using MediatR;
using Movies.Application.Mappers;
using Movies.Application.Queries;
using Movies.Application.Responses;
using Movies.Core.Repositories;
namespace Movies.Application.Handlers;
public class GetMoviesByDirectorNameHandler: IRequestHandler<GetMoviesByDirectorNameQuery, IEnumerable<MovieResponse>>
{
private readonly IMovieRepository _movieRepository;
public GetMoviesByDirectorNameHandler(IMovieRepository movieRepository)
{
_movieRepository = movieRepository;
}
public async Task<IEnumerable<MovieResponse>> Handle(GetMoviesByDirectorNameQuery request, CancellationToken cancellationToken)
{
var movieList = await _movieRepository.GetMoviesByDirectorName(request.DirectorName);
var movieResponseList = MovieMapper.Mapper.Map<IEnumerable<MovieResponse>>(movieList);
return movieResponseList;
}
}
clean-architecture-master\Movies.Application\Handlers\GetMoviesHandler.cs
using MediatR;
using Movies.Application.Mappers;
using Movies.Application.Queries;
using Movies.Application.Responses;
using Movies.Core.Repositories;
namespace Movies.Application.Handlers;
public class GetMoviesHandler : IRequestHandler<GetMoviesQuery, IEnumerable<MovieResponse>>
{
private readonly IMovieRepository _movieRepository;
public GetMoviesHandler(IMovieRepository movieRepository)
{
_movieRepository = movieRepository;
}
public async Task<IEnumerable<MovieResponse>> Handle(
GetMoviesQuery request,
CancellationToken cancellationToken
)
{
var movieList = await _movieRepository.GetMovies();
var movieResponseList = MovieMapper.Mapper.Map<IEnumerable<MovieResponse>>(movieList);
return movieResponseList;
}
}
clean-architecture-master\Movies.Application\Mappers\MovieMapper.cs
using AutoMapper;
namespace Movies.Application.Mappers;
public class MovieMapper
{
private static readonly Lazy<IMapper> Lazy = new(() =>
{
var config = new MapperConfiguration(cfg =>
{
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
cfg.AddProfile<MovieMappingProfile>();
});
var mapper = config.CreateMapper();
return mapper;
});
public static IMapper Mapper => Lazy.Value;
}
clean-architecture-master\Movies.Application\Mappers\MovieMappingProfile.cs
using AutoMapper;
using Movies.Application.Commands;
using Movies.Application.Responses;
using Movies.Core.Entities;
namespace Movies.Application.Mappers;
public class MovieMappingProfile : Profile
{
public MovieMappingProfile()
{
CreateMap<Movie, MovieResponse>().ReverseMap();
CreateMap<Movie, CreateMovieCommand>().ReverseMap();
}
}
clean-architecture-master\Movies.Application\Queries\GetMoviesByDirectorNameQuery.cs
using MediatR;
using Movies.Application.Responses;
namespace Movies.Application.Queries;
public class GetMoviesByDirectorNameQuery : IRequest<IEnumerable<MovieResponse>>
{
public string DirectorName { get; set; }
public GetMoviesByDirectorNameQuery(string directorName)
{
DirectorName = directorName;
}
}
clean-architecture-master\Movies.Application\Queries\GetMoviesQuery.cs
using MediatR;
using Movies.Application.Responses;
namespace Movies.Application.Queries;
public class GetMoviesQuery : IRequest<IEnumerable<MovieResponse>>
{
public string DirectorName { get; set; }
public GetMoviesQuery()
{
}
}
clean-architecture-master\Movies.Application\Responses\MovieResponse.cs
namespace Movies.Application.Responses;
public class MovieResponse
{
public int Id { get; set; }
public string MovieName { get; set; }
public string DirectorName { get; set; }
public string ReleaseYear { get; set; }
}
clean-architecture-master\Movies.Core\Movies.Core.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
clean-architecture-master\Movies.Core\Entities\Movie.cs
using Movies.Core.Entities.Base;
namespace Movies.Core.Entities;
public class Movie : Entity
{
public string MovieName { get; set; }
public string DirectorName { get; set; }
public string ReleaseYear { get; set; }
}
clean-architecture-master\Movies.Core\Entities\Base\Entity.cs
namespace Movies.Core.Entities.Base;
public abstract class Entity: EntityBase<int>
{
}
clean-architecture-master\Movies.Core\Entities\Base\EntityBase.cs
namespace Movies.Core.Entities.Base;
public abstract class EntityBase<TId>: IEntityBase<TId>
{
public virtual TId Id { get; protected set; }
}
clean-architecture-master\Movies.Core\Entities\Base\IEntityBase.cs
namespace Movies.Core.Entities.Base;
public interface IEntityBase<TId>
{
TId Id { get; }
}
clean-architecture-master\Movies.Core\Repositories\IMovieRepository.cs
using Movies.Core.Entities;
using Movies.Core.Repositories.Base;
namespace Movies.Core.Repositories;
public interface IMovieRepository : IRepository<Movie>
{
//here we can have all custom operations
Task<IEnumerable<Movie>> GetMoviesByDirectorName(string directorName);
Task<IEnumerable<Movie>> GetMovies();
}
clean-architecture-master\Movies.Core\Repositories\Base\IRepository.cs
using Movies.Core.Entities.Base;
namespace Movies.Core.Repositories.Base;
public interface IRepository<T> where T: Entity
{
Task<IReadOnlyList<T>> GetAllAsync();
Task<T> GetByIdAsync(int id);
Task<T> AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(T entity);
}
clean-architecture-master\Movies.DbMigrator\appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
clean-architecture-master\Movies.DbMigrator\appsettings.json
{
"ConnectionStrings": {
"MovieConnection": "Data Source=localhost;Initial Catalog=cqrsdb;User ID=sa;Password=xxxxx..;Trust Server Certificate=True"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information"
}
},
"AllowedHosts": "*"
}
clean-architecture-master\Movies.DbMigrator\Movies.DbMigrator.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Movies.Application\Movies.Application.csproj" />
<ProjectReference Include="..\Movies.Infrastructure\Movies.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.14">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>
clean-architecture-master\Movies.DbMigrator\Program.cs
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Movies.Infrastructure.Data;
var builder = WebApplication.CreateBuilder(args);
//数据库上下文注入
builder.Services.AddDbContext<MovieContext>(options =>
{
var msSqlConnection =
builder.Configuration.GetConnectionString("MovieConnection")
?? throw new InvalidOperationException("MsSqlConnection在appsettings.json未发现");
options.UseSqlServer(
msSqlConnection,
b => b.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName)
);
});
var app = builder.Build();
app.Run();
clean-architecture-master\Movies.DbMigrator\Migrations\20240924122651_init.cs
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Movies.DbMigrator.Migrations
{
public partial class init : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Movies",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
MovieName = table.Column<string>(type: "nvarchar(max)", nullable: false),
DirectorName = table.Column<string>(type: "nvarchar(max)", nullable: false),
ReleaseYear = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Movies", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Movies");
}
}
}
clean-architecture-master\Movies.DbMigrator\Migrations\20240924122651_init.Designer.cs
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Movies.Infrastructure.Data;
#nullable disable
namespace Movies.DbMigrator.Migrations
{
[DbContext(typeof(MovieContext))]
[Migration("20240924122651_init")]
partial class init
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.14")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("Movies.Core.Entities.Movie", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("DirectorName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("MovieName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ReleaseYear")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Movies");
});
#pragma warning restore 612, 618
}
}
}
clean-architecture-master\Movies.DbMigrator\Migrations\MovieContextModelSnapshot.cs
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Movies.Infrastructure.Data;
#nullable disable
namespace Movies.DbMigrator.Migrations
{
[DbContext(typeof(MovieContext))]
partial class MovieContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.14")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("Movies.Core.Entities.Movie", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("DirectorName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("MovieName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ReleaseYear")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Movies");
});
#pragma warning restore 612, 618
}
}
}
clean-architecture-master\Movies.DbMigrator\Properties\launchSettings.json
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:43658",
"sslPort": 44346
}
},
"profiles": {
"Movies.DbMigrator": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7110;http://localhost:5267",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
clean-architecture-master\Movies.Infrastructure\Movies.Infrastructure.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Movies.Application\Movies.Application.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.14">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.14">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
clean-architecture-master\Movies.Infrastructure\Data\MovieContext.cs
using Microsoft.EntityFrameworkCore;
using Movies.Core.Entities;
namespace Movies.Infrastructure.Data;
public class MovieContext : DbContext
{
public MovieContext(DbContextOptions<MovieContext> options):base(options)
{
}
public DbSet<Movie> Movies { get; set; }
}
clean-architecture-master\Movies.Infrastructure\Data\MovieContextSeed.cs
using Microsoft.Extensions.Logging;
using Movies.Core.Entities;
namespace Movies.Infrastructure.Data;
public class MovieContextSeed
{
public static async Task SeedAsync(
MovieContext movieContext,
ILoggerFactory loggerFactory,
int? retry = 0
)
{
int retryForAvailability = retry.Value;
try
{
await movieContext.Database.EnsureCreatedAsync();
if (!movieContext.Movies.Any())
{
movieContext.Movies.AddRange(GetMovies());
await movieContext.SaveChangesAsync();
}
}
catch (Exception ex)
{
if (retryForAvailability < 3)
{
retryForAvailability++;
var log = loggerFactory.CreateLogger<MovieContextSeed>();
log.LogError($"Exception occured while connecting: {ex.Message}");
await SeedAsync(movieContext, loggerFactory, retryForAvailability);
}
}
}
private static IEnumerable<Movie> GetMovies()
{
return new List<Movie>()
{
new Movie
{
MovieName = "Avatar",
DirectorName = "James Cameron",
ReleaseYear = "2009"
},
new Movie
{
MovieName = "Titanic",
DirectorName = "James Cameron",
ReleaseYear = "1997"
},
new Movie
{
MovieName = "Die Another Day",
DirectorName = "Lee Tamahori",
ReleaseYear = "2002"
},
new Movie
{
MovieName = "Godzilla",
DirectorName = "Gareth Edwards",
ReleaseYear = "2014"
}
};
}
}
clean-architecture-master\Movies.Infrastructure\Repositories\MovieRepository.cs
using Microsoft.EntityFrameworkCore;
using Movies.Core.Entities;
using Movies.Core.Repositories;
using Movies.Infrastructure.Data;
using Movies.Infrastructure.Repositories.Base;
namespace Movies.Infrastructure.Repositories;
public class MovieRepository : Repository<Movie>, IMovieRepository
{
public MovieRepository(MovieContext movieContext)
: base(movieContext) { }
public async Task<IEnumerable<Movie>> GetMovies()
{
return await _movieContext.Movies.ToListAsync();
}
public async Task<IEnumerable<Movie>> GetMoviesByDirectorName(string directorName)
{
return await _movieContext.Movies.Where(m => m.DirectorName == directorName).ToListAsync();
}
}
clean-architecture-master\Movies.Infrastructure\Repositories\Base\Repository.cs
using Microsoft.EntityFrameworkCore;
using Movies.Core.Entities.Base;
using Movies.Core.Repositories.Base;
using Movies.Infrastructure.Data;
namespace Movies.Infrastructure.Repositories.Base;
public class Repository<T>: IRepository<T> where T: Entity
{
protected readonly MovieContext _movieContext;
public Repository(MovieContext movieContext)
{
_movieContext = movieContext;
}
public async Task<IReadOnlyList<T>> GetAllAsync()
{
return await _movieContext.Set<T>().ToListAsync();
}
public async Task<T> GetByIdAsync(int id)
{
return await _movieContext.Set<T>().FindAsync(id);
}
public async Task<T> AddAsync(T entity)
{
await _movieContext.Set<T>().AddAsync(entity);
await _movieContext.SaveChangesAsync();
return entity;
}
public async Task UpdateAsync(T entity)
{
_movieContext.Entry(entity).State = EntityState.Modified;
await _movieContext.SaveChangesAsync();
}
public async Task DeleteAsync(T entity)
{
_movieContext.Set<T>().Remove(entity);
await _movieContext.SaveChangesAsync();
}
}
clean-architecture-master\Movies.Jobs\Movies.Jobs.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Quartz" Version="3.8.1" />
<PackageReference Include="Quartz.AspNetCore" Version="3.8.1" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.8.1" />
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.8.1" />
</ItemGroup>
</Project>
clean-architecture-master\Movies.Jobs\PickingAndShipping.cs
using Quartz;
namespace Movies.Jobs;
[DisallowConcurrentExecution]
public class PickingAndShippingJob : IJob
{
public PickingAndShippingJob() { }
public async Task Execute(IJobExecutionContext context)
{
System.Console.WriteLine("PickingAndShippingJob");
}
}
clean-architecture-master\.gitignore
clean-architecture-master\global.json
{
"sdk": {
"version": "6.0.423"
}
}
clean-architecture-master\Movies.sln
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35219.272
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Movies.API", "Movies.API\Movies.API.csproj", "{D08D2F3C-5A18-4A9A-B77B-E8E1CA579569}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Movies.Core", "Movies.Core\Movies.Core.csproj", "{417E1DB0-9A20-4CF2-B24A-58BB11382D66}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Movies.Application", "Movies.Application\Movies.Application.csproj", "{0636C245-5345-4DE2-92CA-ADDE7C05184F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Movies.Infrastructure", "Movies.Infrastructure\Movies.Infrastructure.csproj", "{98E91355-30AA-42AD-B1C0-260952157F55}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Movies.DbMigrator", "Movies.DbMigrator\Movies.DbMigrator.csproj", "{5B15484E-B632-4B1F-9783-69E37720C03D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Movies.Jobs", "Movies.Jobs\Movies.Jobs.csproj", "{05FE109D-BA8A-4A0D-B0BD-B0AF34A41497}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D08D2F3C-5A18-4A9A-B77B-E8E1CA579569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D08D2F3C-5A18-4A9A-B77B-E8E1CA579569}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D08D2F3C-5A18-4A9A-B77B-E8E1CA579569}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D08D2F3C-5A18-4A9A-B77B-E8E1CA579569}.Release|Any CPU.Build.0 = Release|Any CPU
{417E1DB0-9A20-4CF2-B24A-58BB11382D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{417E1DB0-9A20-4CF2-B24A-58BB11382D66}.Debug|Any CPU.Build.0 = Debug|Any CPU
{417E1DB0-9A20-4CF2-B24A-58BB11382D66}.Release|Any CPU.ActiveCfg = Release|Any CPU
{417E1DB0-9A20-4CF2-B24A-58BB11382D66}.Release|Any CPU.Build.0 = Release|Any CPU
{0636C245-5345-4DE2-92CA-ADDE7C05184F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0636C245-5345-4DE2-92CA-ADDE7C05184F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0636C245-5345-4DE2-92CA-ADDE7C05184F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0636C245-5345-4DE2-92CA-ADDE7C05184F}.Release|Any CPU.Build.0 = Release|Any CPU
{98E91355-30AA-42AD-B1C0-260952157F55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98E91355-30AA-42AD-B1C0-260952157F55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98E91355-30AA-42AD-B1C0-260952157F55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98E91355-30AA-42AD-B1C0-260952157F55}.Release|Any CPU.Build.0 = Release|Any CPU
{5B15484E-B632-4B1F-9783-69E37720C03D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B15484E-B632-4B1F-9783-69E37720C03D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B15484E-B632-4B1F-9783-69E37720C03D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B15484E-B632-4B1F-9783-69E37720C03D}.Release|Any CPU.Build.0 = Release|Any CPU
{05FE109D-BA8A-4A0D-B0BD-B0AF34A41497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05FE109D-BA8A-4A0D-B0BD-B0AF34A41497}.Debug|Any CPU.Build.0 = Debug|Any CPU
{05FE109D-BA8A-4A0D-B0BD-B0AF34A41497}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05FE109D-BA8A-4A0D-B0BD-B0AF34A41497}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
clean-architecture-master\run.bat
cd Movies.API
dotnet run
clean-architecture-master\zz.bat
set "scriptPath=%cd%"
D: && cd D:\dotnet.-script\App\bin\Debug\net8.0\ && D:\dotnet.-script\App\bin\Debug\net8.0\App.exe "%scriptPath%" "Question" "other"