日常生活的交流与学习

首页 新随笔 联系 管理

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.metadata.v9.bin

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"


  












posted on 2024-09-25 23:15  lazycookie  阅读(9)  评论(0编辑  收藏  举报