diff --git a/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs b/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs
index 6ff36cbd..fd6fb2f7 100644
--- a/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs
+++ b/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs
@@ -26,10 +26,6 @@ protected internal AbstractBootstrap()
PopulateDefaults();
}
- ///
- /// Populate all UpdateOptions with their best-practice defaults.
- /// Subclasses can override to customize.
- ///
protected virtual void PopulateDefaults()
{
Option(UpdateOptions.MaxConcurrency, 3);
@@ -45,9 +41,6 @@ protected virtual void PopulateDefaults()
protected abstract Task ExecuteStrategyAsync();
protected abstract TBootstrap StrategyFactory();
- ///
- /// Setting update configuration.
- ///
public TBootstrap Option(UpdateOption option, T value)
{
if (value == null)
@@ -86,6 +79,9 @@ public TBootstrap Option(UpdateOption option, T value)
public TBootstrap BinaryDiffer() where T : Differential.IBinaryDiffer, new()
{ _extensions[typeof(Differential.IBinaryDiffer)] = typeof(T); return (TBootstrap)this; }
+ public TBootstrap PipelineFactory() where T : Pipeline.IUpdatePipelineFactory, new()
+ { _extensions[typeof(Pipeline.IUpdatePipelineFactory)] = typeof(T); return (TBootstrap)this; }
+
public TBootstrap DownloadPolicy() where T : Download.Abstractions.IDownloadPolicy, new()
{ _extensions[typeof(Download.Abstractions.IDownloadPolicy)] = typeof(T); return (TBootstrap)this; }
@@ -95,6 +91,9 @@ public TBootstrap Option(UpdateOption option, T value)
public TBootstrap DownloadSource() where T : Download.Abstractions.IDownloadSource, new()
{ _extensions[typeof(Download.Abstractions.IDownloadSource)] = typeof(T); return (TBootstrap)this; }
+ public TBootstrap DownloadPipeline() where T : Download.Abstractions.IDownloadPipeline, new()
+ { _extensions[typeof(Download.Abstractions.IDownloadPipeline)] = typeof(T); return (TBootstrap)this; }
+
public TBootstrap UpdateReporter() where T : Download.Reporting.IUpdateReporter, new()
{ _extensions[typeof(Download.Reporting.IUpdateReporter)] = typeof(T); return (TBootstrap)this; }
diff --git a/src/c#/GeneralUpdate.Core/FileSystem/BlackListConfigBuilder.cs b/src/c#/GeneralUpdate.Core/FileSystem/BlackListConfigBuilder.cs
new file mode 100644
index 00000000..3fa46b10
--- /dev/null
+++ b/src/c#/GeneralUpdate.Core/FileSystem/BlackListConfigBuilder.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using GeneralUpdate.Core.Configuration;
+
+namespace GeneralUpdate.Core.FileSystem;
+
+///
+/// Fluent builder for .
+/// Used via Bootstrap.ConfigureBlackList(cfg => cfg.AddBlackFiles(...)).
+///
+public class BlackListConfigBuilder
+{
+ private readonly List _blackFiles = new();
+ private readonly List _blackFormats = new();
+ private readonly List _skipDirectories = new();
+
+ public BlackListConfigBuilder AddBlackFiles(params string[] files)
+ {
+ _blackFiles.AddRange(files);
+ return this;
+ }
+
+ public BlackListConfigBuilder AddBlackFormats(params string[] formats)
+ {
+ _blackFormats.AddRange(formats);
+ return this;
+ }
+
+ public BlackListConfigBuilder AddSkipDirectories(params string[] directories)
+ {
+ _skipDirectories.AddRange(directories);
+ return this;
+ }
+
+ public BlackListConfig Build() => new(
+ BlackFiles: _blackFiles.Count > 0 ? _blackFiles.AsReadOnly() : null,
+ BlackFormats: _blackFormats.Count > 0 ? _blackFormats.AsReadOnly() : null,
+ SkipDirectorys: _skipDirectories.Count > 0 ? _skipDirectories.AsReadOnly() : null
+ );
+}
diff --git a/src/c#/GeneralUpdate.Core/Pipeline/IUpdatePipelineFactory.cs b/src/c#/GeneralUpdate.Core/Pipeline/IUpdatePipelineFactory.cs
new file mode 100644
index 00000000..962b4264
--- /dev/null
+++ b/src/c#/GeneralUpdate.Core/Pipeline/IUpdatePipelineFactory.cs
@@ -0,0 +1,14 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace GeneralUpdate.Core.Pipeline;
+
+///
+/// Factory for creating update pipelines.
+/// Injected via Bootstrap.PipelineFactory<T>().
+///
+public interface IUpdatePipelineFactory
+{
+ /// Create a pipeline for the given context.
+ Task ExecutePipelineAsync(PipelineContext context, CancellationToken token = default);
+}