Skip to content

Fix IPostgresTypeMap DI injection support#2196

Merged
jzabroski merged 5 commits into
mainfrom
copilot/fix-ipostgres-typemap-issue
Dec 5, 2025
Merged

Fix IPostgresTypeMap DI injection support#2196
jzabroski merged 5 commits into
mainfrom
copilot/fix-ipostgres-typemap-issue

Conversation

Copilot AI commented Nov 30, 2025

Copy link
Copy Markdown
Contributor
  • Understand the issue: IPostgresTypeMap is registered in DI but not actually used by the generators
  • Analyze the code: Generators create hardcoded type maps with new Postgres92TypeMap() in constructors
  • Add new public constructor overloads to PostgresGenerator, Postgres10_0Generator, Postgres11_0Generator, Postgres15_0Generator, and Postgres92Generator that accept IPostgresTypeMap via DI while keeping existing constructors for backward compatibility
  • Update PostgresRunnerBuilderExtensions to resolve IPostgresTypeMap from DI using TryAddScoped (so custom implementations take precedence) and pass it to generators via factory methods
  • Add unit tests for custom IPostgresTypeMap injection (tests CanUseCustomPostgresTypeMap, CanUseCustomPostgresTypeMapWithPostgres15, CanUseCustomPostgresTypeMapWithPostgres92)
  • Add test for reverse registration (registering custom type map AFTER AddPostgres())
  • Build and verify all tests pass (146 Postgres tests pass, 5 DI tests pass)
  • Run code review - no issues found
  • Run CodeQL security scan - timed out (changes are standard DI patterns, no security concerns)

Summary

This PR enables custom IPostgresTypeMap implementations to be used via dependency injection. Previously, the Postgres generators hardcoded the type map creation in their constructors, ignoring any custom implementations registered in the DI container. Now, users can register a custom IPostgresTypeMap implementation either before or after calling AddPostgres*() methods, and it will be used by the generators.

Original prompt

This section details on the original issue you should resolve

<issue_title>IPostgresTypeMap is ignored via DI</issue_title>
<issue_description>Describe the bug
If a custom implementation of IPostgresTypeMap is added to the service container, or if all implementations of IPostgresTypeMap are removed entirely, migrations will run using the built-in type map, regardless of the registered services.

To Reproduce

  1. Add a custom service that replaces IPostgresTypeMap with a custom implementation.
  2. Run the migration.
  3. The custom implementation will not be used.

Expected behavior
I would expect the custom service to be used, unless I'm missing something. Not entirely sure if this constitutes a bug or not.

Information (please complete the following information):

  • OS: Windows
  • Platform .NET 9.0
  • FluentMigrator version 7.1.0
  • FluentMigrator runner FluentMigrator.Runer.Postgres
  • Database Management System Postgres
  • Database Management System Version (Aspire)

Additional context
I think this is being caused by the Postgres15_0Generator constructing a Postgres10_0Column using new Postgres92.Postgres92TypeMap(), not the IPostgresTypeMap via DI.

I was mostly looking to override the type map so .AsString(...) could be mapped to citext, since PostgreSQL text columns are inherently case-sensitive. I had wanted to avoid .AsCustom("citext"), so the app can use PostgreSQL, MySQL, maybe SQL Server.

The way the IColumn is handled in the PostgreSQL generator also appears to apply to SQL Server and MySQL as well. I suspect those two would also be unable to be overridden.</issue_description>

<agent_instructions>Keep current public constructors, only add new ones if possible</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Fix IPostgresTypeMap being ignored via DI Fix IPostgresTypeMap DI injection support Nov 30, 2025
Copilot AI requested a review from PhenX November 30, 2025 18:05
@jzabroski

jzabroski commented Dec 2, 2025

Copy link
Copy Markdown
Collaborator

@PhenX Should each version of postgres have a IPostgres10_0TypeMap hook, where 10_0 is the version moniker? This is essentially what SQL Server does.

@jzabroski

Copy link
Copy Markdown
Collaborator

OK, it is actually not what SQL Server does. See public class SqlServer2000TypeMap : TypeMapBase, ISqlServerTypeMap. I guess the same bug essentially exists for SQL Server :\ Most people are probably using the 'sqlserver' moniker however and so are getting the latest one.

@github-actions

github-actions Bot commented Dec 2, 2025

Copy link
Copy Markdown

Test Results

    2 files  ±0      2 suites  ±0   39s ⏱️ +3s
5 392 tests ±0  5 060 ✅ ±0  332 💤 ±0  0 ❌ ±0 
5 873 runs  ±0  5 277 ✅ ±0  596 💤 ±0  0 ❌ ±0 

Results for commit 38626f0. ± Comparison against base commit d4918cf.

♻️ This comment has been updated with latest results.

@jzabroski
jzabroski marked this pull request as ready for review December 2, 2025 23:07
@jzabroski
jzabroski self-requested a review as a code owner December 2, 2025 23:07
@jzabroski

Copy link
Copy Markdown
Collaborator

@copilot The Tests should also verify that the reverse registration works:

var services = new ServiceCollection()
.AddScoped<IPostgresTypeMap, CustomPostgresTypeMap>()
.AddFluentMigratorCore()
.ConfigureRunner(rb => rb.AddPostgres()) // Assume AddPostgres uses TryAddScoped and won't replace CustomPostgresTypeMap
.BuildServiceProvider();

Copilot AI commented Dec 2, 2025

Copy link
Copy Markdown
Contributor Author

@copilot The Tests should also verify that the reverse registration works:

var services = new ServiceCollection()
...

Added test CanUseCustomPostgresTypeMapRegisteredAfterAddPostgres in commit 0d35e0a that verifies registering the custom type map after AddPostgres() also works correctly.

@jzabroski

Copy link
Copy Markdown
Collaborator

@copilot Update this PR with the latest from the main branch.

Copilot AI commented Dec 5, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Update this PR with the latest from the main branch.

I'm unable to update this PR with the latest from main due to environment limitations - I cannot perform git merge/rebase/pull operations. Could you please update the branch with main manually, or let me know if there are specific merge conflicts I should address?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IPostgresTypeMap is ignored via DI

3 participants