Posted on 25/08/2025 17:07:20
Hi Alex
Great question — this is one of the common stumbling blocks when moving from Dynamicweb 9 (ASP.NET Framework + System.Web
) to Dynamicweb 10 (ASP.NET Core).
Why Standard.Application.AfterStart
is Obsolete
-
In DW9, notifications like Standard.Application.AfterStart
were tied to the old System.Web lifecycle (Global.asax
, HttpApplication.Start
, etc.).
-
In DW10, that entire pipeline is gone because it now runs on ASP.NET Core middleware.
→ Notifications like AfterStart
don’t exist anymore.
On Dynamicweb 10 you can use middleware and iPipeline to hook into something similar to the above notication - something down the line of this:
using Dynamicweb.Host.Core;
namespace ChemicarDiscount;
public class DiscountPipeline : IPipeline
{
// Determines ordering relative to built-in middleware (use >100 to be safe)
public int Rank => 150;
public void RegisterServices(IServiceCollection services, IMvcCoreBuilder mvcBuilder)
{
// Only needed if you have custom services to register
}
public void RegisterApplicationComponents(IApplicationBuilder app)
{
// Only needed if you add custom middleware or routing
}
public void RunInitializers()
{
// This runs once when the DW10 application starts
Data.InitializeDiscountTable();
}
}
I am pretty sure that what you do in the application start is not the best way to do it - Data.InitializeDiscountTable()does not sound like an application wide functionality that belongs in the application bootup.
Table initialization sounds like domain logic that belongs inside a discount service or similar, not global application startup.
That way, your code becomes lazy-initialized: the first time you use your CustomDiscountService
, it ensures the table exists before doing real work.
Example: Lazy Initialization Inside the Service
using System;
namespace ChemicarDiscount
{
public class CustomDiscountService
{
private static bool _initialized = false;
private static readonly object _lock = new();
private void EnsureInitialized()
{
if (_initialized) return;
lock (_lock)
{
if (!_initialized)
{
Data.InitializeDiscountTable();
_initialized = true;
}
}
}
public decimal GetDiscount(string productId, string customerId)
{
EnsureInitialized();
// Example: query the custom discount table
var discount = Data.GetDiscountForCustomer(productId, customerId);
return discount;
}
}
}
Why this is Better
-
Encapsulated: CustomDiscountService
owns both initialization and usage.
-
Lazy: InitializeDiscountTable
only runs if/when someone calls the service.
-
Thread-safe: Uses a lock to prevent race conditions on the first request.
-
Reusable: If you later register CustomDiscountService
in DI, everything just works.