11// Copyright (c) Atlas Lift Tech Inc. All rights reserved.
22
3+ using Microsoft . AspNetCore . Builder ;
4+ using Microsoft . AspNetCore . Hosting . Server ;
35using Microsoft . Extensions . DependencyInjection ;
46using MQTTnet . AspNetCore . Routing ;
7+ using MQTTnet . AspNetCore . Routing . Routing ;
58using MQTTnet . Server ;
69using System ;
710using System . Reflection ;
811using System . Runtime . CompilerServices ;
12+ using System . Text . Encodings . Web ;
913using System . Text . Json ;
14+ using System . Text . Unicode ;
1015
1116// This is needed to make internal classes visible to UnitTesting projects
1217[ assembly: InternalsVisibleTo ( "MQTTnet.AspNetCore.Routing.Tests, PublicKey=00240000048000009" +
@@ -19,40 +24,123 @@ namespace MQTTnet.AspNetCore.Routing
1924{
2025 public static class ServiceCollectionExtensions
2126 {
22- public static IServiceCollection AddMqttControllers ( this IServiceCollection services , Assembly [ ] fromAssemblies = null )
27+ public static IServiceCollection AddMqttControllers ( this IServiceCollection services , Assembly [ ] fromAssemblies )
2328 {
29+ return services . AddMqttControllers ( opt => opt . FromAssemblies = fromAssemblies ) ;
30+ }
31+ public static IServiceCollection AddMqttControllers ( this IServiceCollection services )
32+ {
33+ return services . AddMqttControllers ( opt => { } ) ;
34+ }
35+ public static IServiceCollection AddMqttControllers ( this IServiceCollection services , Action < MqttRoutingOptions > _options )
36+ {
37+ var _opt = new MqttRoutingOptions ( ) ;
38+ _opt . WithJsonSerializerOptions ( ) ;
39+ _opt . FromAssemblies = null ;
40+ _opt . RouteInvocationInterceptor = null ;
41+ _options ? . Invoke ( _opt ) ;
42+
43+ services . AddSingleton ( _opt ) ;
2444 services . AddSingleton ( _ =>
2545 {
46+
47+ var fromAssemblies = _opt . FromAssemblies ;
2648 if ( fromAssemblies != null && fromAssemblies . Length == 0 )
2749 {
2850 throw new ArgumentException ( "'fromAssemblies' cannot be an empty array. Pass null or a collection of 1 or more assemblies." , nameof ( fromAssemblies ) ) ;
2951 }
30-
3152 var assemblies = fromAssemblies ?? new Assembly [ ] { Assembly . GetEntryAssembly ( ) } ;
3253
3354 return MqttRouteTableFactory . Create ( assemblies ) ;
3455 } ) ;
3556
3657 services . AddSingleton < ITypeActivatorCache > ( new TypeActivatorCache ( ) ) ;
3758 services . AddSingleton < MqttRouter > ( ) ;
38-
59+ if ( _opt . RouteInvocationInterceptor == null )
60+ {
61+ services . AddSingleton ( typeof ( IRouteInvocationInterceptor ) , _opt . RouteInvocationInterceptor ) ;
62+ }
3963 return services ;
4064 }
65+ public static void WithRouteInvocationInterceptor < T > ( this MqttRoutingOptions opt ) where T : IRouteInvocationInterceptor
66+ {
67+ opt . RouteInvocationInterceptor = typeof ( T ) ;
68+ }
69+ public static MqttRoutingOptions WithJsonSerializerOptions ( this MqttRoutingOptions opt )
70+ {
71+ #if NET5_0_OR_GREATER
72+ var jopt = new JsonSerializerOptions ( JsonSerializerDefaults . Web ) ;
73+ #else
74+ var jopt = new JsonSerializerOptions ( ) ;
75+ jopt . PropertyNameCaseInsensitive = true ;
76+ #endif
77+ jopt . Encoder = JavaScriptEncoder . Create ( UnicodeRanges . All ) ;
78+ opt . SerializerOptions = jopt ;
79+ return opt ;
80+ }
81+
82+ public static MqttRoutingOptions WithJsonSerializerOptions ( this MqttRoutingOptions opt , JsonSerializerOptions options )
83+ {
84+ opt . SerializerOptions = options ;
85+ return opt ;
86+ }
4187
88+
89+ [ Obsolete ( "Use 'services.AddMqttControllers(opt => opt.SerializerOptions= new JsonSerializerOptions());' instead " ) ]
4290 public static IServiceCollection AddMqttDefaultJsonOptions ( this IServiceCollection services ,
4391 JsonSerializerOptions options )
4492 {
45- services . AddSingleton ( new MqttDefaultJsonOptions ( options ) ) ;
93+ services . AddSingleton ( new MqttRoutingOptions ( ) { SerializerOptions = options } ) ;
4694 return services ;
4795 }
4896
97+ public static IApplicationBuilder UseAttributeRouting ( this IApplicationBuilder app , bool allowUnmatchedRoutes = false )
98+ {
99+ var router = app . ApplicationServices . GetRequiredService < MqttRouter > ( ) ;
100+ var server = app . ApplicationServices . GetRequiredService < MqttServer > ( ) ;
101+ var interceptor = app . ApplicationServices . GetService < IRouteInvocationInterceptor > ( ) ;
102+ server . InterceptingPublishAsync += async ( args ) =>
103+ {
104+ await interceptor ? . RouteExecuting ( args . ClientId , args . ApplicationMessage ) ;
105+ try
106+ {
107+ await router . OnIncomingApplicationMessage ( app . ApplicationServices , args , allowUnmatchedRoutes ) ;
108+ }
109+ catch ( Exception ex )
110+ {
111+ await interceptor ? . RouteExecuted ( args , ex ) ;
112+ if ( interceptor == null )
113+ {
114+ throw ;
115+ }
116+ }
117+ } ;
118+ return app ;
119+ }
120+
121+ [ Obsolete ( "Use UseAttributeRouting instead" ) ]
49122 public static void WithAttributeRouting ( this MqttServer server , IServiceProvider svcProvider , bool allowUnmatchedRoutes = false )
50123 {
51124 var router = svcProvider . GetRequiredService < MqttRouter > ( ) ;
125+ var interceptor = svcProvider . GetRequiredService < IRouteInvocationInterceptor > ( ) ;
52126 server . InterceptingPublishAsync += async ( args ) =>
53127 {
54- await router . OnIncomingApplicationMessage ( svcProvider , args , allowUnmatchedRoutes ) ;
128+ await interceptor ? . RouteExecuting ( args . ClientId , args . ApplicationMessage ) ;
129+ try
130+ {
131+ await router . OnIncomingApplicationMessage ( svcProvider , args , allowUnmatchedRoutes ) ;
132+ }
133+ catch ( Exception ex )
134+ {
135+ await interceptor ? . RouteExecuted ( args , ex ) ;
136+ if ( interceptor == null )
137+ {
138+ throw ;
139+ }
140+ }
55141 } ;
56142 }
143+
144+
57145 }
58146}
0 commit comments