Skip to content

Migration Guide: Old God Package → New Packages

Section: 16 — Packages
Last Updated: 2026-05-30
Scope: Namespace mapping, step-by-step migration, common patterns


Background

The original ERP codebase used a single monolithic NuGet package (nicknamed the "God Package") that contained everything: domain primitives, persistence, messaging, web middleware, and more. This created:

  • Tight coupling — changing one thing forced rebuilding everything
  • Slow CI — every service rebuild required a full God Package rebuild
  • Difficult versioning — all-or-nothing upgrades
  • Growing transitive dependencies in every service

The God Package was split into the current 16-package architecture. This guide covers migrating services that still reference old namespaces.


Namespace Mapping Table

Shared.Core → Microtec.Domain

Old NamespaceNew NamespaceNotes
Shared.Core.Domain.EntitiesMicrotec.Domain.Entities
Shared.Core.Domain.BaseEntityMicrotec.Domain.BaseEntity
Shared.Core.Domain.AggregateRootMicrotec.Domain.AggregateRoot
Shared.Core.Domain.AuditableEntityMicrotec.Domain.AuditableEntity
Shared.Core.Domain.TenantEntityMicrotec.Domain.TenantEntity
Shared.Core.Interfaces.ITenantProviderMicrotec.Domain.ITenantProvider
Shared.Core.Interfaces.IClockServiceMicrotec.Domain.IClockService
Shared.Core.Services.IScopedServiceMicrotec.Domain.IScopedService
Shared.Core.Services.ITransientServiceMicrotec.Domain.ITransientService
Shared.Core.Exceptions.DomainExceptionMicrotec.Domain.DomainException
Shared.Core.Exceptions.NotFoundExceptionMicrotec.Domain.NotFoundException
Shared.Core.Results.Result<T>Microtec.Domain.Result<T>Same interface
Shared.Core.ValueObjects.*Microtec.Domain.ValueObjects.*

Shared.Core → Microtec.Contracts

Old NamespaceNew NamespaceNotes
Shared.Core.CQRS.ICommandMicrotec.Contracts.ICommand
Shared.Core.CQRS.IQuery<T>Microtec.Contracts.IQuery<T>
Shared.Core.CQRS.ICommandHandler<T>Microtec.Contracts.ICommandHandler<T>
Shared.Core.DTOs.PagedResult<T>Microtec.Contracts.PagedResult<T>
Shared.Core.DTOs.APIResponse<T>Microtec.Contracts.APIResponse<T>
Shared.Core.Events.IIntegrationEventMicrotec.Contracts.IIntegrationEvent
Shared.Core.DTOs.DropdownDtoMicrotec.Contracts.DropdownDto
Shared.Core.DTOs.PagedRequestMicrotec.Contracts.PagedRequest

Shared.Infrastructure → Microtec.Persistence

Old NamespaceNew NamespaceNotes
Shared.Infrastructure.Data.RepositoryBase<T>Microtec.Persistence.RepositoryBase<T>
Shared.Infrastructure.Data.IRepository<T>Microtec.Persistence.IRepository<T>
Shared.Infrastructure.Data.IUnitOfWork<T>Microtec.Persistence.IUnitOfWork<T>Same interface
Shared.Infrastructure.Data.IAdminUnitOfWorkMicrotec.Persistence.IAdminUnitOfWork
Shared.Infrastructure.Interceptors.AuditInterceptorMicrotec.Persistence.AuditInterceptor
Shared.Infrastructure.Extensions.*Microtec.Persistence.Extensions.*

Shared.Infrastructure → Microtec.Messaging

Old NamespaceNew NamespaceNotes
Shared.Infrastructure.Messaging.IEventPublisherMicrotec.Messaging.IEventPublisher
Shared.Infrastructure.Messaging.EventPublisherMicrotec.Messaging.EventPublisher
Shared.Infrastructure.Cache.IDistributedCacheServiceMicrotec.Messaging.IDistributedCacheService
Shared.Infrastructure.Bus.*Microtec.Messaging.*MassTransit wrappers

Shared.Web → Microtec.Web.Core

Old NamespaceNew NamespaceNotes
Shared.Web.Middleware.TenantMiddlewareMicrotec.Web.Core.TenantMiddleware
Shared.Web.Middleware.ErrorHandlingMiddlewareMicrotec.Web.Core.ErrorHandlingMiddleware
Shared.Web.Auth.*Microtec.Web.Core.Auth.*
Shared.Web.Services.ICurrentUserServiceMicrotec.Web.Core.ICurrentUserService
Shared.Web.Behaviors.*Microtec.Web.Core.Behaviors.*
Shared.Web.Extensions.AddSharedWebServices()Microtec.Web.Core.AddMicrotecAuthentication()Different method name

Shared.Web → Microtec.Web.Hosting

Old NamespaceNew NamespaceNotes
Shared.Web.Hosting.AddSharedHosting()Microtec.Web.Hosting.AddMicrotecHosting()
Shared.Web.Telemetry.*Microtec.Web.Hosting.*
Shared.Web.Logging.*Microtec.Web.Hosting.*Serilog config moved here

Step-by-Step Migration for a Service

Step 1: Update .csproj References

Remove old God Package references, add new packages:

xml
<!-- BEFORE (old) -->
<PackageReference Include="Microtec.Shared.Core" Version="1.x.x" />
<PackageReference Include="Microtec.Shared.Infrastructure" Version="1.x.x" />
<PackageReference Include="Microtec.Shared.Web" Version="1.x.x" />

<!-- AFTER (new) -->
<PackageReference Include="Microtec.Web.Hosting" Version="2.3.1" />
<PackageReference Include="Microtec.Persistence" Version="2.3.1" />
<PackageReference Include="Microtec.Messaging" Version="2.3.1" />

NOTE

Microtec.Web.Hosting pulls in Web.Core transitively. Microtec.Domain and Microtec.Contracts come transitively through Persistence and Messaging. You typically only need to reference Tier 3 packages directly.

Step 2: Update Program.cs

csharp
// BEFORE (old)
builder.Services.AddSharedWebServices(builder.Configuration);
builder.Services.AddSharedHosting(builder.Configuration);
builder.Services.AddSharedPersistence<MyDbContext>(builder.Configuration);

// AFTER (new)
builder.AddMicrotecHosting(o => o.ServiceName = "my-service");
builder.Services
    .AddMicrotecAuthentication(builder.Configuration)
    .AddMicrotecAuthorization()
    .AddMicrotecPersistence<MyDbContext>(builder.Configuration)
    .AddMicrotecMessaging(builder.Configuration, consumers =>
    {
        consumers.AddConsumer<MyEventHandler>();
    });

Step 3: Update Using Statements

Use the IDE's "Find & Replace" with the mapping table above, or run:

bash
# Example: Replace Shared.Core.Domain with Microtec.Domain
find . -name "*.cs" -exec sed -i '' \
  's/using Shared\.Core\.Domain/using Microtec.Domain/g' {} +

find . -name "*.cs" -exec sed -i '' \
  's/using Shared\.Core\.CQRS/using Microtec.Contracts/g' {} +

find . -name "*.cs" -exec sed -i '' \
  's/using Shared\.Infrastructure\.Data/using Microtec.Persistence/g' {} +

find . -name "*.cs" -exec sed -i '' \
  's/using Shared\.Web/using Microtec.Web.Core/g' {} +

Step 4: Update DbContext

csharp
// BEFORE
public class MyDbContext : SharedDbContextBase
{
    public MyDbContext(DbContextOptions<MyDbContext> options,
                       ITenantProvider tenantProvider)
        : base(options, tenantProvider) { }
}

// AFTER
public class MyDbContext : DbContext
{
    private readonly ITenantProvider _tenantProvider;

    public MyDbContext(DbContextOptions<MyDbContext> options,
                       ITenantProvider tenantProvider)
        : base(options)
    {
        _tenantProvider = tenantProvider;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
        modelBuilder.ConfigureDecimalPrecision(18, 4);
        modelBuilder.ApplyGlobalQueryFilters(_tenantProvider);
    }
}

Step 5: Verify Build

bash
cd Platforms
dotnet restore
dotnet build Microtec.Platforms.sln --no-incremental 2>&1 | grep -E "error|warning"

Step 6: Run Tests

bash
dotnet test --filter "FullyQualifiedName~{ServiceName}" --logger trx

Common Migration Issues

Issue: AddSharedWebServices not found

Cause: Old extension method removed in Microtec.Web.Core.

Fix: Replace with the new method chain:

csharp
// Old
services.AddSharedWebServices(config);

// New
services.AddMicrotecAuthentication(config)
        .AddMicrotecAuthorization()
        .AddMicrotecLocalization();

Issue: AuditableEntity has no TenantId

Cause: TenantId was moved to TenantEntity (separate class) in the new packages. Not all entities need multi-tenancy.

Fix: Change base class from AuditableEntity to TenantEntity if the entity is tenant-scoped.

Issue: ConfigureDecimalPrecision not found in OnModelCreating

Cause: Extension method lives in Microtec.Persistence.Extensions.

Fix: Add using Microtec.Persistence.Extensions;

Issue: ICurrentUserService missing after migration

Cause: It moved from Shared.Web.Services to Microtec.Web.Core.

Fix: Update using statement. The interface contract is identical.

Issue: Tenant query filter stops working

Cause: ApplyGlobalQueryFilters() must be called after ApplyConfigurationsFromAssembly().

Fix:

csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);  // First
    modelBuilder.ConfigureDecimalPrecision(18, 4);
    modelBuilder.ApplyGlobalQueryFilters(_tenantProvider);             // Last
}

Verification Checklist

After migration:

  • [ ] dotnet build succeeds with no errors
  • [ ] dotnet test passes all existing tests
  • [ ] Swagger loads at /swagger in dev
  • [ ] Health check responds at /health
  • [ ] Tenant isolation verified (query returns only current tenant's data)
  • [ ] Audit fields populated (CreatedBy, UpdatedBy not null after create/update)
  • [ ] No references to old Shared.* namespaces remain
bash
# Verify no old namespaces remain
grep -r "using Shared\." src/ --include="*.cs" | grep -v ".cs.bak"
# Should return empty

Internal Documentation — Microtec Platform Team