@@ -112,4 +112,113 @@ public ValueTask InvokeAsync(
112112
113113 Assert . DoesNotContain ( diagnostics , diagnostic => diagnostic . Id == "DP024" ) ;
114114 }
115+
116+ [ Fact ]
117+ public async Task DoesNotTreatForeignHandlerOrderAsRegisteredContext ( )
118+ {
119+ const string source = """
120+ using System;
121+ using System.Threading;
122+ using System.Threading.Tasks;
123+ using DesignPatterns.Behavioral;
124+
125+ namespace Other
126+ {
127+ [AttributeUsage(AttributeTargets.Class)]
128+ public sealed class HandlerOrderAttribute : Attribute
129+ {
130+ public HandlerOrderAttribute(int order, Type contextType) { }
131+ }
132+ }
133+
134+ namespace TestAssembly
135+ {
136+ public sealed class RequestContext
137+ {
138+ }
139+
140+ [Other.HandlerOrder(10, typeof(RequestContext))]
141+ public sealed class LoggingHandler : IHandler<RequestContext>
142+ {
143+ public ValueTask InvokeAsync(
144+ RequestContext context,
145+ HandlerDelegate<RequestContext> next,
146+ CancellationToken cancellationToken = default) =>
147+ default;
148+ }
149+
150+ public sealed class AuditHandler : IHandler<RequestContext>
151+ {
152+ public ValueTask InvokeAsync(
153+ RequestContext context,
154+ HandlerDelegate<RequestContext> next,
155+ CancellationToken cancellationToken = default) =>
156+ default;
157+ }
158+ }
159+ """ ;
160+
161+ var diagnostics = await AnalyzerTestContext . RunAnalyzersAsync (
162+ source ,
163+ new UnregisteredHandlerAnalyzer ( ) ) ;
164+
165+ Assert . DoesNotContain ( diagnostics , diagnostic => diagnostic . Id == "DP024" ) ;
166+ }
167+
168+ [ Fact ]
169+ public async Task ReportsWhenOnlyForeignHandlerOrderIsPresentOnImplementation ( )
170+ {
171+ const string source = """
172+ using System;
173+ using System.Threading;
174+ using System.Threading.Tasks;
175+ using DesignPatterns.Behavioral;
176+
177+ namespace Other
178+ {
179+ [AttributeUsage(AttributeTargets.Class)]
180+ public sealed class HandlerOrderAttribute<TContext> : Attribute
181+ {
182+ public HandlerOrderAttribute(int order) { }
183+ }
184+ }
185+
186+ namespace TestAssembly
187+ {
188+ public sealed class RequestContext
189+ {
190+ }
191+
192+ [DesignPatterns.Behavioral.HandlerOrder<RequestContext>(10)]
193+ public sealed class LoggingHandler : IHandler<RequestContext>
194+ {
195+ public ValueTask InvokeAsync(
196+ RequestContext context,
197+ HandlerDelegate<RequestContext> next,
198+ CancellationToken cancellationToken = default) =>
199+ default;
200+ }
201+
202+ [Other.HandlerOrder<RequestContext>(20)]
203+ public sealed class AuditHandler : IHandler<RequestContext>
204+ {
205+ public ValueTask InvokeAsync(
206+ RequestContext context,
207+ HandlerDelegate<RequestContext> next,
208+ CancellationToken cancellationToken = default) =>
209+ default;
210+ }
211+ }
212+ """ ;
213+
214+ var diagnostics = await AnalyzerTestContext . RunAnalyzersAsync (
215+ source ,
216+ new UnregisteredHandlerAnalyzer ( ) ) ;
217+
218+ Assert . Contains (
219+ diagnostics ,
220+ diagnostic =>
221+ diagnostic . Id == "DP024" &&
222+ diagnostic . GetMessage ( ) . Contains ( "AuditHandler" , StringComparison . Ordinal ) ) ;
223+ }
115224}
0 commit comments