• I


    namespace Library
    {
        using Automatonymous;
        using MassTransit;
        using MassTransit.EntityFrameworkCoreIntegration;
        using MassTransit.EntityFrameworkCoreIntegration.Mappings;
        using MassTransit.ExtensionsDependencyInjectionIntegration;
        using Microsoft.AspNetCore.Builder;
        using Microsoft.AspNetCore.Hosting;
        using Microsoft.AspNetCore.Mvc;
        using Microsoft.AspNetCore.Routing;
        using Microsoft.EntityFrameworkCore;
        using Microsoft.EntityFrameworkCore.Metadata.Builders;
        using Microsoft.Extensions.Configuration;
        using Microsoft.Extensions.DependencyInjection;
        using Microsoft.Extensions.Hosting;
        using Microsoft.Extensions.Logging;
        using System;
        using System.Collections.Generic;
        using System.Threading.Tasks;
    
        public class Program
        {
            public static void Main(string[] args)
            {
                CreateHostBuilder(args).Build().Run();
            }
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(host => host.UseStartup<Startup>());
        }
        public class Startup
        {
            public IConfiguration Configuration { get; }
            public Startup(IConfiguration configuration) => Configuration = configuration;
            public void ConfigureServices(IServiceCollection svcs)
            {
                svcs.AddDbContext<LibraryContext>(opts => opts
                    .UseSqlServer(Configuration.GetConnectionString("Library")));
                svcs.AddMassTransit(MassTransitConfigure);
                svcs.AddMassTransitHostedService();
                svcs.AddControllers();
            }
            public void Configure(IApplicationBuilder budr)
            {
                budr.UseRouting();
                budr.UseEndpoints(rute => rute.MapControllers());
            }
            public void MassTransitConfigure(IServiceCollectionBusConfigurator cfgr)
            {
                cfgr.AddSagaStateMachine<BookStateMachine, Book>()
                    .EntityFrameworkRepository(cfg => cfg.ExistingDbContext<LibraryContext>());
    
                cfgr.AddSagaStateMachine<ReserveStateMachine, Reserve>()
                    .EntityFrameworkRepository(cfg => cfg.ExistingDbContext<LibraryContext>());
    
                cfgr.UsingRabbitMq((ctx, cfg) =>
                {
                    cfg.Host("localhost", "/", hst =>
                    {
                        hst.Username("guest");
                        hst.Password("guest");
                    });
                    cfg.ConfigureEndpoints(ctx);
                });
            }
        }
    
        public class LibraryContext : SagaDbContext
        {
            public LibraryContext(DbContextOptions<LibraryContext> options) : base(options) { }
            public DbSet<Book> Books { get; set; }
            public DbSet<Reserve> Reserves { get; set; }
            protected override IEnumerable<ISagaClassMap> Configurations
            {
                get
                {
                    yield return new BookMap();
                    yield return new ReserveMap();
                }
            }
        }
    
        public class Book : SagaStateMachineInstance
        {
            public Guid CorrelationId { get; set; }
            public int State { get; set; }
            public DateTime Timestamp { get; set; }
        }
        public class BookMap : SagaClassMap<Book>
        {
            protected override void Configure(EntityTypeBuilder<Book> entity, ModelBuilder model)
            {
                base.Configure(entity, model);
                entity.ToTable(nameof(Book));
            }
        }
        public class BookStateMachine : MassTransitStateMachine<Book>
        {
            public ILogger<BookStateMachine> Logger { get; }
            public BookStateMachine(ILogger<BookStateMachine> logger)
            {
                Logger = logger;
    
                InstanceState(ins => ins.State, Created, Reserved);
    
                Event(() => BookCreated, cfg => cfg.CorrelateById(ctx => ctx.Message.BookId));
    
                Event(() => ReserveCreated, cfg => cfg.CorrelateById(ctx => ctx.Message.BookId));
    
                Initially(
                    When(BookCreated)
                        .Then(ctx =>
                        {
                            ctx.Instance.Timestamp = ctx.Data.Timestamp;
                        })
                        .TransitionTo(Created));
    
                During(Created,
                    When(ReserveCreated)
                        .TransitionTo(Reserved)
                        .PublishAsync(ctx => ctx.Init<BookReserved>(new
                        {
                            ReserveId = ctx.Data.ReserveId,
                            Timestamp = ctx.Data.Timestamp,
                            BookId = ctx.Data.BookId // ctx.Instance.CorrelationId
                        })));
            }
            public State Created { get; }
            public State Reserved { get; }
            public Event<BookCreated> BookCreated { get; }
            public Event<ReserveCreated> ReserveCreated { get; }
        }
        public class BookController : ControllerBase
        {
            public ILogger<BookController> Logger { get; }
            public IPublishEndpoint PublishEndpoint { get; }
            public BookController(
                ILogger<BookController> logger,
                IPublishEndpoint publishEndpoint)
            {
                Logger = logger;
                PublishEndpoint = publishEndpoint;
            }
    
            [HttpGet, Route("api/books/create/{bookId}")]
            public async Task<IActionResult> CreateAsync(Guid bookId)
            {
                await PublishEndpoint.Publish<BookCreated>(new
                {
                    BookId = bookId,
                    Timestamp = InVar.Timestamp
                });
                return Ok(bookId);
            }
        }
    
        public interface BookCreated
        {
            Guid BookId { get; }
            DateTime Timestamp { get; }
        }
        public interface ReserveCreated
        {
            Guid ReserveId { get; }
            DateTime Timestamp { get; }
            Guid BookId { get; }
        }
        public interface BookReserved
        {
            Guid ReserveId { get; }
            DateTime Timestamp { get; }
            Guid BookId { get; }
        }
    
        public class Reserve : SagaStateMachineInstance
        {
            public Guid CorrelationId { get; set; }
            public int State { get; set; }
            public DateTime Timestamp { get; set; }
            public Guid BookId { get; set; }
        }
        public class ReserveMap : SagaClassMap<Reserve>
        {
            protected override void Configure(EntityTypeBuilder<Reserve> entity, ModelBuilder model)
            {
                base.Configure(entity, model);
                entity.ToTable(nameof(Reserve));
            }
        }
        public class ReserveStateMachine : MassTransitStateMachine<Reserve>
        {
            public ILogger<ReserveStateMachine> Logger { get; }
            public ReserveStateMachine(ILogger<ReserveStateMachine> logger)
            {
                Logger = logger;
    
                InstanceState(ins => ins.State, Created, Reserved);
    
                Event(() => ReserveCreated, cfg => cfg.CorrelateById(ctx => ctx.Message.ReserveId));
    
                Event(() => BookReserved, cfg => cfg.CorrelateById(ctx => ctx.Message.ReserveId));
    
                Initially(
                    When(ReserveCreated)
                        .Then(ctx =>
                        {
                            ctx.Instance.Timestamp = ctx.Data.Timestamp;
                            ctx.Instance.BookId = ctx.Data.BookId;
                        })
                        .TransitionTo(Created));
    
                During(Created,
                    When(BookReserved)
                        .TransitionTo(Reserved));
            }
            public State Created { get; }
            public State Reserved { get; }
            public Event<ReserveCreated> ReserveCreated { get; }
            public Event<BookReserved> BookReserved { get; }
        }
        public class ReserveController : ControllerBase
        {
            public ILogger<ReserveController> Logger { get; }
            public IPublishEndpoint PublishEndpoint { get; }
            public ReserveController(
                ILogger<ReserveController> logger,
                IPublishEndpoint publishEndpoint)
            {
                Logger = logger;
                PublishEndpoint = publishEndpoint;
            }
    
            [HttpGet, Route("api/reserves/create/{reserveId}/{bookId}")]
            public async Task<IActionResult> Create(Guid reserveId, Guid bookId)
            {
                await PublishEndpoint.Publish<ReserveCreated>(new
                {
                    ReserveId = reserveId,
                    Timestamp = InVar.Timestamp,
                    BookId = bookId
                });
                return Ok(reserveId);
            }
        }
    }
  • 相关阅读:
    登录界面
    冲刺一阶段(5月9日)-个人总结07
    冲刺一阶段(5月8日)-个人总结06
    冲刺一阶段(5月7日)-个人总结05
    冲刺一阶段(5月6日)-个人总结04
    冲刺一阶段(5月5日)-个人总结03
    冲刺一阶段(5月4日)-个人总结02
    第一阶段冲刺--个人总结01(忘记发了)
    软件需求分析(补发)
    第八周工作进程表
  • 原文地址:https://www.cnblogs.com/xiaowangzhi/p/14328659.html
Copyright © 2020-2023  润新知