The recommended entry point is `SharpCompressClient` in the `SharpCompress` namespace. Its constructor accepts an optional immutable `SharpCompressConfiguration` containing `Formats` and `Providers`. The client implements `ISharpCompressClient` and exposes independently injectable workflow services:
| API | Purpose |
| --- | --- |
| `client.OpenArchive(...)` / `OpenAsyncArchive(...)` | Random access to seekable archives |
Open methods accept paths, `FileInfo`, or streams. Archive opening also accepts ordered lists of files or streams for multipart archives. Async methods accept `CancellationToken`. The caller disposes returned archives, readers, and writers; the reusable client needs no disposal. Client services may be shared concurrently when custom factories and providers are thread-safe. Individual opened archives/readers/writers remain operation-local.
```csharp
using SharpCompress;
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Writers;
var client = new SharpCompressClient();
using var archive = client.OpenArchive("archive.zip");
client.Extractor.ExtractToDirectory(archive, "output", new ExtractionOptions());
var detection = client.Inspector.DetectArchive("archive.tar.gz");
var information = await client.Inspector.InspectArchiveAsync(
`IArchiveInspector`, `IArchiveExtractor`, and `IArchiveFileWriter` are in `SharpCompress.Archives`. `ArchiveExtractor` is a public stateless implementation, and `ArchiveFileWriter` can be constructed with a `SharpCompressConfiguration` or defaults. Applications can constructor-inject these interfaces separately, or use the client properties. No public API requires Pure.DI.
### Extraction Service
-`ExtractToDirectory(IArchive, ...)` and `ExtractToDirectoryAsync(IAsyncArchive, ...)` extract all entries, handling solid archives sequentially. They accept extraction options and an optional archive-level progress reporter.
-`ExtractToDirectory(IReader, ...)` and its `IAsyncReader` equivalent advance to and extract every remaining unread entry.
-`ExtractEntryToDirectory(IReader, ...)` and its async equivalent extract only the current entry.
- Entry overloads of `ExtractToDirectory`, `ExtractToFile`, and `ExtractToStream` operate on `IArchiveEntry`; reader overloads of `ExtractToFile` and `ExtractToStream` operate on the current reader entry.
- Extraction leaves supplied archives/readers/destination streams open. Directory extraction requires an existing destination and retains path/link protection, overwrite and metadata options. File/directory extraction validates checksums by default. Archive-entry stream extraction validates optional checksums when an `ExtractionOptions` value is supplied, matching `entry.WriteTo(...)` behavior.
### Filesystem Writing Service
`WriteFile` and `WriteDirectory` accept `IWriter`; their async equivalents accept `IAsyncWriter`. Directory writing accepts a search pattern, optional `Func<string, bool>` filter, and `SearchOption`. Entry paths are relative to the source directory and use `/` separators. `AddFile` and `AddDirectory` operate on writable archives, transferring accepted file-stream ownership to the archive. Async versions accept cancellation tokens. `SaveToFile<TOptions>` and `SaveToFileAsync<TOptions>` save to a `FileInfo` using the client's default providers unless the supplied options explicitly override them.
### Format Configuration
`FormatRegistry` is in `SharpCompress.Factories`. It copies its input collections and exposes read-only `Factories` and `TarWrappers` lists. `Default` contains built-in factories in recognition order; `Empty` contains neither factories nor wrappers. A constructor supplied only factories uses the default wrappers. Use `WithTarWrappers(...)` to select wrappers explicitly.
`With(factory, prepend: false)` creates a copy. A matching known archive type is replaced in place; custom formats with no known type match by ordinal name. New formats append by default; `prepend: true` places a new format first. Factory ordering is explicit and consistent across opening and inspection. `WithTarWrappers(...)` also recomputes the required rewind-buffer size. Factories can implement `IFactory` and capability interfaces directly without deriving from `Factory`.
Provider precedence is **explicit operation options → client configuration → built-in default**. Explicitly assigning `CompressionProviderRegistry.Default` overrides a custom client default. Client operations copy built-in reader/writer options before resolving dependencies, preserving caller-owned settings and format-specific fields. Custom `IWriterOptions` implementations retain their own provider settings and are passed to their custom factory unchanged.
| Removed `Factory.Factories` | `client.Configuration.Formats.Factories` on the concrete client |
Async usages follow the equivalent async service methods. Static convenience factories and workflow extensions delegate to the immutable default client's instance services. Their configuration is independent of custom clients. `TarWrapper.Wrappers` now exposes `IReadOnlyList<TarWrapper>` instead of a mutable array; use `FormatRegistry.WithTarWrappers(...)` for customization.
`DetectArchive` identifies the logical container, its outer compression wrapper, and whether the Archive and Reader APIs are available without enumerating entries. Compressed TAR wrappers such as `.tar.gz` and `.tar.xz` are identified as `ArchiveType.Tar` with an outer compression type and `ArchiveAccessMode.Reader`.
`InspectArchive` enumerates metadata and returns `ArchiveInformation`. It reports `Partial` status for missing volumes or encrypted headers without a password; malformed archives and incorrect passwords throw. ZIP-specific metadata is exposed through `ArchiveInformation.Zip`.
`ArchiveInformation.Detection` contains the format identification collected during inspection, so there is no need to call `DetectArchive` first when requesting metadata. Inspection reuses the selected factory and compression wrapper to open the source.
`Status.Complete` means no known inspection limitations apply; it does not guarantee that every nullable metadata property has a value. `EntriesWithUnknownSizeCount` counts entries whose uncompressed sizes a forward-only reader cannot know before reading their data. For example, ZIP inspection can obtain final sizes from the central directory while still reporting entries with deferred local-header sizes.
The stream overloads of `DetectArchive` and `InspectArchive` preserve the supplied stream's position and leave it open, including when `ReaderOptions.LeaveStreamOpen` is `false`.
#### Migrating from `GetArchiveInformation`
| Removed API | Replacement |
| --- | --- |
| `GetArchiveInformation(...)` used only to identify a format | `DetectArchive(...)` |
| `GetArchiveInformation(...)` used to enumerate archive details | `InspectArchive(...)` |
| `GetArchiveInformationAsync(...)` | `DetectArchiveAsync(...)` or `InspectArchiveAsync(...)` |
`WriterOptions.BufferSize` controls stream copy buffers used while writing archive entries. If it is not set, SharpCompress falls back to `Constants.BufferSize`.
`WriterOptions.EnableParallelism` (also available on `ZipWriterOptions`, `TarWriterOptions`, `GZipWriterOptions`, and `SevenZipWriterOptions`) opts in to a format's optional parallel encode. No writer currently implements parallel encoding, so this is a no-op today; it is reserved for future use and mirrors `ReaderOptions.EnableParallelism`.
`CheckCrc` validates archive-level payload checksums when the format stores reliable metadata, such as ZIP CRC32 values. Formats without payload checksums skip this validation. Decompressor integrity checks that are required to decode a stream may still fail even when `CheckCrc` is disabled.
When using `SymbolicLinkHandler`, directory extraction rejects link targets outside the extraction root and never follows symbolic links or reparse points while extracting later entries. The handler itself remains trusted application code.
`ReaderOptions` and `WriterOptions` expose a `Providers` registry that controls which `ICompressionProvider` implementations are used for each `CompressionType`. The registry defaults to `CompressionProviderRegistry.Default`, so you only need to set it if you want to swap in a custom provider (for example the `SystemGZipCompressionProvider` or `SystemDeflateCompressionProvider`). The selected registry is honored by Reader/Writer APIs, Archive APIs, and async entry-stream extraction paths.
GetCompressingProvider(type): returns ICompressionProviderHooks when available
```
`ICompressionProvider` implementations declare their `CompressionType`, whether they support compression/decompression, and create sync/async streams. For simple providers, derive from `CompressionProviderBase`; it supplies default async implementations that delegate to the synchronous methods. For read-only codecs, derive from `DecompressionOnlyProviderBase`.
```csharp
public sealed class CustomGZipProvider : CompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.GZip;
public override bool SupportsCompression => true;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel) =>
new GZipStream(destination, CompressionMode.Compress, leaveOpen: false);
public override Stream CreateDecompressStream(Stream source) =>
new GZipStream(source, CompressionMode.Decompress, leaveOpen: false);
}
```
`CompressionContext` carries metadata that providers may need when creating streams, including `InputSize`, `OutputSize`, `Properties`, `CanSeek`, `FormatOptions`, and `ReaderOptions`. Use `CompressionContext.FromStream(stream)` to populate stream-derived values, `WithReaderOptions(...)` to attach reader metadata, and `ResolveArchiveEncoding()` to get the archive header encoding from the context.
When a format needs additional initialization/finalization data (LZMA, PPMd, etc.) the registry exposes `GetCompressingProvider` which returns the `ICompressionProviderHooks` contract; the rest of the API continues to flow through `Providers`, including pre/properties/post compression hook data.