@@ -186,17 +186,24 @@ private Tuple<Type, string> SearchForStartupAttribute(string friendlyName, IList
186
186
Assembly matchedAssembly = null ;
187
187
foreach ( var assembly in _referencedAssemblies )
188
188
{
189
- object [ ] attributes ;
189
+ Attribute [ ] attributes ;
190
190
try
191
191
{
192
- attributes = assembly . GetCustomAttributes ( inherit : false ) ;
192
+ // checking attribute's name first and only then instantiating it
193
+ // then we are filtering attributes by name second time as inheritors could be added by calling to GetCustomAttributes(type)
194
+ attributes = assembly . GetCustomAttributesData ( )
195
+ . Where ( data => MatchesStartupAttribute ( data . AttributeType ) )
196
+ . Select ( data => data . AttributeType )
197
+ . SelectMany ( type => assembly . GetCustomAttributes ( type ) )
198
+ . Distinct ( )
199
+ . ToArray ( ) ;
193
200
}
194
201
catch ( CustomAttributeFormatException )
195
202
{
196
203
continue ;
197
204
}
198
-
199
- foreach ( var owinStartupAttribute in attributes . Where ( attribute => attribute . GetType ( ) . Name . Equals ( Constants . OwinStartupAttribute , StringComparison . Ordinal ) ) )
205
+
206
+ foreach ( var owinStartupAttribute in attributes . Where ( attribute => MatchesStartupAttribute ( attribute . GetType ( ) ) ) )
200
207
{
201
208
Type attributeType = owinStartupAttribute . GetType ( ) ;
202
209
foundAnyInstances = true ;
@@ -265,6 +272,11 @@ private Tuple<Type, string> SearchForStartupAttribute(string friendlyName, IList
265
272
}
266
273
return fullMatch ;
267
274
}
275
+
276
+ private static bool MatchesStartupAttribute ( Type type )
277
+ {
278
+ return type . Name . Equals ( Constants . OwinStartupAttribute , StringComparison . Ordinal ) ;
279
+ }
268
280
269
281
// Search for any assemblies with a Startup or [AssemblyName].Startup class.
270
282
private Tuple < Type , string > SearchForStartupConvention ( IList < string > errors )
0 commit comments