@@ -488,6 +488,11 @@ protected virtual void Initialize()
488
488
}
489
489
}
490
490
LoadBuiltinBindings ( usedBindingTypes ) ;
491
+
492
+ var directTypes = GetDirectTypes ( functionMetadata ) ;
493
+
494
+ LoadDirectlyReferencesExtensions ( directTypes ) ;
495
+
491
496
LoadCustomExtensions ( ) ;
492
497
493
498
// Do this after we've loaded the custom extensions. That gives an extension an opportunity to plug in their own implementations.
@@ -517,7 +522,7 @@ protected virtual void Initialize()
517
522
List < Type > types = new List < Type > ( ) ;
518
523
types . Add ( type ) ;
519
524
520
- AddDirectTypes ( types , functions ) ;
525
+ types . AddRange ( directTypes ) ;
521
526
522
527
hostConfig . TypeLocator = new TypeLocator ( types ) ;
523
528
@@ -614,13 +619,14 @@ private void VerifyPrecompileStatus(IEnumerable<FunctionDescriptor> functions)
614
619
}
615
620
}
616
621
617
- private static void AddDirectTypes ( List < Type > types , Collection < FunctionDescriptor > functions )
622
+ // Get the set of types that should be directly loaded. These have the "configurationSource" : "attributes" set.
623
+ // They will be indexed and invoked directly by the WebJobs SDK and skip the IL generator and invoker paths.
624
+ private static IEnumerable < Type > GetDirectTypes ( IEnumerable < FunctionMetadata > functionMetadatas )
618
625
{
619
626
HashSet < Type > visitedTypes = new HashSet < Type > ( ) ;
620
627
621
- foreach ( var function in functions )
628
+ foreach ( var metadata in functionMetadatas )
622
629
{
623
- var metadata = function . Metadata ;
624
630
if ( ! metadata . IsDirect )
625
631
{
626
632
continue ;
@@ -632,11 +638,9 @@ private static void AddDirectTypes(List<Type> types, Collection<FunctionDescript
632
638
Assembly assembly = Assembly . LoadFrom ( path ) ;
633
639
var type = assembly . GetType ( typeName ) ;
634
640
635
- if ( visitedTypes . Add ( type ) )
636
- {
637
- types . Add ( type ) ;
638
- }
641
+ visitedTypes . Add ( type ) ;
639
642
}
643
+ return visitedTypes ;
640
644
}
641
645
642
646
private IMetricsLogger CreateMetricsLogger ( )
@@ -697,6 +701,19 @@ private void LoadCustomExtensions(string extensionsPath)
697
701
}
698
702
}
699
703
704
+ // Load extensions that are directly references by the user types.
705
+ private void LoadDirectlyReferencesExtensions ( IEnumerable < Type > userTypes )
706
+ {
707
+ var possibleExtensionAssemblies = UserTypeScanner . GetPossibleExtensionAssemblies ( userTypes ) ;
708
+
709
+ foreach ( var kv in possibleExtensionAssemblies )
710
+ {
711
+ var assembly = kv . Key ;
712
+ var locationHint = kv . Value ;
713
+ LoadExtensions ( assembly , locationHint ) ;
714
+ }
715
+ }
716
+
700
717
private void LoadExtensions ( Assembly assembly , string locationHint )
701
718
{
702
719
foreach ( var type in assembly . ExportedTypes )
@@ -706,11 +723,31 @@ private void LoadExtensions(Assembly assembly, string locationHint)
706
723
continue ;
707
724
}
708
725
726
+ if ( IsExtensionLoaded ( type ) )
727
+ {
728
+ continue ;
729
+ }
730
+
709
731
IExtensionConfigProvider instance = ( IExtensionConfigProvider ) Activator . CreateInstance ( type ) ;
710
732
LoadExtension ( instance , locationHint ) ;
711
733
}
712
734
}
713
735
736
+ private bool IsExtensionLoaded ( Type type )
737
+ {
738
+ var registry = this . ScriptConfig . HostConfig . GetService < IExtensionRegistry > ( ) ;
739
+ var extensions = registry . GetExtensions < IExtensionConfigProvider > ( ) ;
740
+ foreach ( var extension in extensions )
741
+ {
742
+ var loadedExtentionType = extension . GetType ( ) ;
743
+ if ( loadedExtentionType == type )
744
+ {
745
+ return true ;
746
+ }
747
+ }
748
+ return false ;
749
+ }
750
+
714
751
// Load a single extension
715
752
private void LoadExtension ( IExtensionConfigProvider instance , string locationHint = null )
716
753
{
0 commit comments