47 lines
4.8 KiB
Markdown
47 lines
4.8 KiB
Markdown
|
|
---
|
|||
|
|
source_files:
|
|||
|
|
- DataPRO/Modules/Database/DatabaseInitializationScripts/EmbeddedResource.cs
|
|||
|
|
generated_at: "2026-04-16T04:35:11.382491+00:00"
|
|||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
|||
|
|
schema_version: 1
|
|||
|
|
sha256: "ae12472d249773d0"
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# DatabaseInitializationScripts
|
|||
|
|
|
|||
|
|
## 1. Purpose
|
|||
|
|
This module provides utilities for reading embedded resources (e.g., SQL scripts, configuration files) from a .NET assembly’s manifest resources. It exists to abstract away the boilerplate of locating and extracting embedded resources by name, particularly supporting scenarios where database initialization scripts are bundled as embedded resources within the assembly. It enables both stream-based and string-based access to such resources, with overloads that allow specifying a custom assembly or defaulting to the assembly containing the `EmbeddedResource` class itself.
|
|||
|
|
|
|||
|
|
## 2. Public Interface
|
|||
|
|
- **`static StreamReader GetStream(Assembly assembly, string name)`**
|
|||
|
|
Searches the manifest resource names of the given `assembly` for a resource whose name *ends with* the provided `name` (case-sensitive substring match), and returns a `StreamReader` for the first matching resource. Returns `null` if no match is found.
|
|||
|
|
*Note: The caller is responsible for disposing the returned `StreamReader`.*
|
|||
|
|
|
|||
|
|
- **`static string GetString(Assembly assembly, string name)`**
|
|||
|
|
Calls `GetStream(assembly, name)`, reads the entire contents of the stream into a string using `ReadToEnd()`, closes the stream, and returns the resulting string. Returns `null` if `GetStream` returns `null`.
|
|||
|
|
*Note: This method disposes the `StreamReader` internally via `sr.Close()`.*
|
|||
|
|
|
|||
|
|
- **`static string GetString(string name)`**
|
|||
|
|
Overload of `GetString` that uses the assembly containing the `EmbeddedResource` class itself (`typeof(EmbeddedResource).Assembly`) as the target assembly. Behaves identically to `GetString(assembly, name)` for that assembly.
|
|||
|
|
|
|||
|
|
## 3. Invariants
|
|||
|
|
- **Substring matching semantics**: Resource lookup uses `EndsWith(name)`, meaning the full manifest resource name must end with the provided `name` string. For example, `GetString("init.sql")` would match `"MyApp.Migrations.init.sql"` but not `"init.sql.bak"`.
|
|||
|
|
- **First-match behavior**: If multiple resources end with the same `name`, only the first one (as returned by `GetManifestResourceNames()`) is used. The order is not guaranteed by the .NET specification and may vary across builds or environments.
|
|||
|
|
- **No validation of resource existence beyond null**: `GetStream` returns `null` if no matching resource is found; callers must handle this case explicitly.
|
|||
|
|
- **Resource names are case-sensitive**: `EndsWith` performs case-sensitive comparison by default in .NET.
|
|||
|
|
|
|||
|
|
## 4. Dependencies
|
|||
|
|
- **Depends on**:
|
|||
|
|
- `System.IO` (for `StreamReader`)
|
|||
|
|
- `System.Reflection.Assembly` (for `GetManifestResourceNames()` and `GetManifestResourceStream()`)
|
|||
|
|
- **Depended on by**:
|
|||
|
|
- Not inferable from this file alone. However, given the namespace (`DatabaseInitializationScripts`), it is highly likely used by database migration or setup logic elsewhere in the codebase (e.g., to load `.sql` files during schema initialization).
|
|||
|
|
- The default `GetString(string)` overload implies a design assumption that the assembly containing `EmbeddedResource` is the one housing the embedded resources—likely the same assembly where this class resides.
|
|||
|
|
|
|||
|
|
## 5. Gotchas
|
|||
|
|
- **Resource name ambiguity**: Because matching is based on `EndsWith`, two resources named `"script1.sql"` and `"subfolder/script1.sql"` would both match a lookup for `"script1.sql"`, and only the first (arbitrary) one would be returned. This can lead to unpredictable behavior if resource naming is not strictly controlled.
|
|||
|
|
- **Resource stream not disposed by caller**: `GetStream` returns an open `StreamReader`; callers must ensure it is disposed (e.g., via `using`), otherwise resource leaks may occur. The `GetString(Assembly, string)` overload avoids this by closing the stream internally, but the stream-returning overload does not.
|
|||
|
|
- **Encoding assumption**: `StreamReader.ReadToEnd()` uses the default encoding of the `StreamReader`, which is UTF-8 *without BOM* by default in modern .NET. If the embedded resource is encoded differently (e.g., UTF-8 with BOM, UTF-16), the string may be misinterpreted.
|
|||
|
|
- **No support for nested paths**: The API does not distinguish between resource names with directory-like separators (e.g., `"Scripts/init.sql"` vs `"init.sql"`), increasing the risk of collisions.
|
|||
|
|
- **`null` return without exception**: `GetStream` returns `null` on failure, which may lead to `NullReferenceException` if callers do not check for it before use.
|
|||
|
|
- **`sr.Close()` is not `Dispose()`**: While `Close()` and `Dispose()` are functionally equivalent for `StreamReader`, using `Close()` instead of `using` or `Dispose()` is outdated style and may obscure resource management intent.
|