66using System ;
77using System . Collections . Generic ;
88using System . Linq ;
9+ using System . Threading ;
910using System . Threading . Tasks ;
1011
11- namespace DevelApp . RuntimePluggableClassFactory . Containerized . Examples
12+ namespace DevelApp . RuntimePluggableClassFactory . Containerized
1213{
1314 /// <summary>
14- /// Example factory that can use both traditional (in-process) and containerized plugins
15- /// This demonstrates how the CRPCF can coexist with the existing RuntimePluggableClassFactory
15+ /// Factory that can use both traditional (in-process) and containerized plugins.
16+ /// Enables async module-based plugin loading from Kubernetes/remote sources and local directories.
17+ /// This allows the CRPCF to coexist with the existing RuntimePluggableClassFactory.
1618 /// </summary>
1719 /// <typeparam name="T">Plugin interface type</typeparam>
1820 public class HybridPluginFactory < T > where T : IPluginClass
@@ -46,12 +48,14 @@ public HybridPluginFactory(
4648 /// <param name="pluginName">Plugin name</param>
4749 /// <param name="version">Plugin version (optional)</param>
4850 /// <param name="executionMode">Preferred execution mode</param>
51+ /// <param name="cancellationToken">Cancellation token</param>
4952 /// <returns>Plugin instance or null if not found</returns>
5053 public async Task < T ? > GetPluginAsync (
5154 NamespaceString moduleName ,
5255 IdentifierString pluginName ,
5356 SemanticVersionNumber ? version = null ,
54- PluginExecutionMode executionMode = PluginExecutionMode . Auto )
57+ PluginExecutionMode executionMode = PluginExecutionMode . Auto ,
58+ CancellationToken cancellationToken = default )
5559 {
5660 _logger . LogDebug ( "Getting plugin {ModuleName}.{PluginName} with execution mode {ExecutionMode}" ,
5761 moduleName , pluginName , executionMode ) ;
@@ -64,14 +68,14 @@ public HybridPluginFactory(
6468 return await GetTraditionalPluginAsync ( moduleName , pluginName , version ) ;
6569
6670 case PluginExecutionMode . Containerized :
67- return await GetContainerizedPluginAsync ( moduleName , pluginName , version ) ;
71+ return await GetContainerizedPluginAsync ( moduleName , pluginName , version , cancellationToken ) ;
6872
6973 case PluginExecutionMode . Auto :
7074 default :
7175 // Try preferred mode first, then fallback
7276 if ( _options . PreferContainerized )
7377 {
74- var containerized = await GetContainerizedPluginAsync ( moduleName , pluginName , version ) ;
78+ var containerized = await GetContainerizedPluginAsync ( moduleName , pluginName , version , cancellationToken ) ;
7579 if ( containerized != null ) return containerized ;
7680
7781 return await GetTraditionalPluginAsync ( moduleName , pluginName , version ) ;
@@ -81,7 +85,7 @@ public HybridPluginFactory(
8185 var traditional = await GetTraditionalPluginAsync ( moduleName , pluginName , version ) ;
8286 if ( traditional != null ) return traditional ;
8387
84- return await GetContainerizedPluginAsync ( moduleName , pluginName , version ) ;
88+ return await GetContainerizedPluginAsync ( moduleName , pluginName , version , cancellationToken ) ;
8589 }
8690 }
8791 }
@@ -95,8 +99,10 @@ public HybridPluginFactory(
9599 /// <summary>
96100 /// Lists all available plugins from both traditional and containerized sources
97101 /// </summary>
102+ /// <param name="cancellationToken">Cancellation token</param>
98103 /// <returns>Available plugins with their execution modes</returns>
99- public async Task < IEnumerable < PluginInfo > > ListAvailablePluginsAsync ( )
104+ public async Task < IEnumerable < PluginInfo > > ListAvailablePluginsAsync (
105+ CancellationToken cancellationToken = default )
100106 {
101107 var plugins = new List < PluginInfo > ( ) ;
102108
@@ -120,7 +126,7 @@ public async Task<IEnumerable<PluginInfo>> ListAvailablePluginsAsync()
120126 // Get containerized plugins
121127 if ( _containerizedOrchestrator != null )
122128 {
123- var containerizedPlugins = await _containerizedOrchestrator . ListPluginsAsync ( ) ;
129+ var containerizedPlugins = await _containerizedOrchestrator . ListPluginsAsync ( null , cancellationToken ) ;
124130 plugins . AddRange ( containerizedPlugins . Select ( p => new PluginInfo
125131 {
126132 ModuleName = p . PluginId . Namespace ,
@@ -150,8 +156,11 @@ public async Task<IEnumerable<PluginInfo>> ListAvailablePluginsAsync()
150156 /// Deploys a NuGet package as a containerized plugin
151157 /// </summary>
152158 /// <param name="request">Deployment request</param>
159+ /// <param name="cancellationToken">Cancellation token</param>
153160 /// <returns>Deployment result</returns>
154- public async Task < PluginDeploymentResult > DeployContainerizedPluginAsync ( PluginDeploymentRequest request )
161+ public async Task < PluginDeploymentResult > DeployContainerizedPluginAsync (
162+ PluginDeploymentRequest request ,
163+ CancellationToken cancellationToken = default )
155164 {
156165 if ( _containerizedOrchestrator == null )
157166 {
@@ -162,7 +171,7 @@ public async Task<PluginDeploymentResult> DeployContainerizedPluginAsync(PluginD
162171
163172 try
164173 {
165- return await _containerizedOrchestrator . DeployPluginAsync ( request ) ;
174+ return await _containerizedOrchestrator . DeployPluginAsync ( request , cancellationToken ) ;
166175 }
167176 catch ( Exception ex )
168177 {
@@ -236,7 +245,11 @@ public void AllowTraditionalPlugin(NamespaceString moduleName, IdentifierString
236245 }
237246 }
238247
239- private async Task < T ? > GetContainerizedPluginAsync ( NamespaceString moduleName , IdentifierString pluginName , SemanticVersionNumber ? version )
248+ private async Task < T ? > GetContainerizedPluginAsync (
249+ NamespaceString moduleName ,
250+ IdentifierString pluginName ,
251+ SemanticVersionNumber ? version ,
252+ CancellationToken cancellationToken = default )
240253 {
241254 if ( _containerizedOrchestrator == null )
242255 {
@@ -250,10 +263,10 @@ public void AllowTraditionalPlugin(NamespaceString moduleName, IdentifierString
250263 {
251264 Namespace = moduleName ,
252265 Name = pluginName ,
253- Version = version ?? new SemanticVersionNumber ( 0 , 0 , 0 ) // Will match latest if version not specified
266+ Version = version ?? new SemanticVersionNumber ( 0 , 0 , 0 ) // Use 0.0.0 as placeholder when version not specified
254267 } ;
255268
256- var pluginInfo = await _containerizedOrchestrator . GetPluginInfoAsync ( pluginId ) ;
269+ var pluginInfo = await _containerizedOrchestrator . GetPluginInfoAsync ( pluginId , cancellationToken ) ;
257270 if ( pluginInfo != null )
258271 {
259272 var proxy = ContainerizedPluginProxyFactory . Create < T > ( _containerizedOrchestrator , pluginInfo ) ;
0 commit comments