我前面幾篇隨筆介紹了關於幾篇關於SqlSugar的基礎封裝,已經可以直接應用在Winform項目開發上,並且基礎介面也通過了單元測試,同時測試通過了一些Winform功能頁面;本篇隨筆繼續深化應用開發,著手在在.net6框架的Web API上開發應用,也就是基於.net core的Web API應用... ...
這篇文章參考網上的教程,主要解決了EasyNetQ的依賴註入服務問題。
主要涉及四個文件:
ApplicationExtenssion.cs .Net中間件的實現
OrderConsumer.cs 消息消費者的實現
WindsorMessageDispatcher.cs 通過容器解析獲得消費者服務
Startup.cs 相關服務的註冊及中間件引用
主要參考代碼:
ApplicationExtenssion.cs
public static class ApplicationExtenssion { /// <summary> /// 中間件實現 /// </summary> /// <param name="appBuilder"></param> /// <param name="subscriptionIdPrefix"></param> /// <param name="assembly"></param> /// <returns></returns> public static IApplicationBuilder UseSubscribe(this IApplicationBuilder appBuilder, string subscriptionIdPrefix, Assembly assembly) { var services = appBuilder.ApplicationServices.CreateScope().ServiceProvider; var lifeTime = services.GetService<IHostApplicationLifetime>(); var bus = services.GetRequiredService<IBus>(); lifeTime.ApplicationStarted.Register(() => { var subscriber = new AutoSubscriber(bus, subscriptionIdPrefix); //需要指定AutoSubscriberMessageDispatcher對應的實例 //並可以通過構造函數傳參,如:IServicesProvider,即:services subscriber.AutoSubscriberMessageDispatcher = new WindsorMessageDispatcher(services); subscriber.Subscribe(new Assembly[] { assembly }); subscriber.SubscribeAsync(new Assembly[] { assembly }); }); lifeTime.ApplicationStopped.Register(() => { bus.Dispose(); }); return appBuilder; } }
OrderConsumer.cs
/// <summary> /// IConsume介面的實現類 /// </summary> public class OrderConsumer : IConsume<MessageDto> { private readonly ILogger<OrderConsumer> logger; /// <summary> /// 可以註入相關服務 /// </summary> /// <param name="logger"></param> public OrderConsumer(ILogger<OrderConsumer> logger) { this.logger = logger; } /// <summary> /// 消息的消費方法 /// </summary> /// <param name="message"></param> /// <param name="cancellationToken"></param> public void Consume(MessageDto message, CancellationToken cancellationToken = default) { logger.LogInformation(JsonConvert.SerializeObject(message)); } }
WindsorMessageDispatcher.cs
/// <summary> /// 結合官方教程實現自動訂閱消息轉發 /// </summary> public class WindsorMessageDispatcher : IAutoSubscriberMessageDispatcher { private readonly IServiceProvider service; /// <summary> /// 參數由中間件的AutoSubscriberMessageDispatcher進行傳遞 /// </summary> /// <param name="service"></param> public WindsorMessageDispatcher(IServiceProvider service) { this.service = service; } /// <summary> /// 同步方法,可以解析TConsumer對應的服務 /// </summary> /// <typeparam name="TMessage"></typeparam> /// <typeparam name="TConsumer"></typeparam> /// <param name="message"></param> /// <param name="cancellationToken"></param> void IAutoSubscriberMessageDispatcher.Dispatch<TMessage, TConsumer>(TMessage message, CancellationToken cancellationToken) { //通過容器獲取對應的消費者服務,也可以通過Autofac實現 var consumer = service.GetService<IConsume<MessageDto>>(); //通過解析到的服務調用對應的消費者實現的方法 consumer.Consume(message as MessageDto, cancellationToken); } /// <summary> /// 非同步方法 /// </summary> /// <typeparam name="TMessage"></typeparam> /// <typeparam name="TConsumer"></typeparam> /// <param name="message"></param> /// <param name="cancellationToken"></param> /// <returns></returns> async Task IAutoSubscriberMessageDispatcher.DispatchAsync<TMessage, TConsumer>(TMessage message, CancellationToken cancellationToken) { var consumer = service.GetService<TConsumer>(); await consumer.ConsumeAsync(message, cancellationToken); } }
Startup.cs
public void ConfigureServices(IServiceCollection services) { string rabbitMqConnection = Configuration["RabbitMqConnection"]; //註冊IBus為單例模式 services.AddSingleton(RabbitHutch.CreateBus(rabbitMqConnection)); //註冊IConsume的實現類,EasyNetQ會自動掃描實現該介面的類 services.AddSingleton<IConsume<MessageDto>,OrderConsumer>(); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "EasyNetQ.WebApi", Version = "v1" }); }); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "EasyNetQ.WebApi v1")); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); //添加相應的中間件 app.UseSubscribe("OrderService", Assembly.GetExecutingAssembly()); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
代碼:https://github.com/superfeeling-git/EasyNetQ