40FINGERS Blog

Using Dependency Injection in your (old) modules

Using Dependency Injection in your (old) modules

14-11-2025

Over the past years, DNN has been deprecating a lot of API methods to services using Dependency Injection. Starting DNN 10, the first batch of "old" API's have actually been removed. So, there's no way back, we need to have a quick and solid way to use the new services, using DI.

For example, in our SEORedirect module, we're using the PortalAliasController:

var portalAliasInfo = PortalAliasController.GetPortalAliasInfo(domainName);

That method has been removed. But we still need it.

I will probably need more services, so I'm looking for a solution that can be easily extended with extra services, and preferrably also be easily applied in other modules in the future.

I decided to make a ServiceHelper class, that will serve as a wrapper for the services I need. This makes sure I don't have to implement DI on every class that's using some kind of service, but instead give me a single class that provides them all. I'll be making this ServiceHelper class a Singleton.

But to be able to use DI in that class, I will need to add it to the services on Dnn Startup. To do that, we need a simple class that implements IDnnStartup:

    public class DnnStartup : IDnnStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // IndexModel registration is required for
            // constructor injection to work
            services.AddSingleton();
        }
    }

Then, I need to create the ServiceHelper class itself:

    public class ServiceHelper
    {
        private static readonly Lazy StaticInstance = new Lazy(() =>
        {
            try
            {
                // we need to get the IServiceProvider from the current HttpContext
                // it's set there by DNN, so contains a lot of the registered services already
                var lsp = HttpContextSource.Current?.GetScope()?.ServiceProvider;
            }
            catch
            {
            }

            return null;
        }, isThreadSafe: true);

        public static ServiceHelper Instance => StaticInstance.Value;

        private IPortalAliasService _portalAliasService;
        internal IPortalAliasService PortalAliasService => _portalAliasService;

        public ServiceHelper(IPortalAliasService portalAliasService)
        {
            _portalAliasService = portalAliasService;
        }
    }

Now, we can change the line from the beginnning to

var portalAliasInfo = ServiceHelper.Instance.PortalAliasService.GetPortalAlias(domainName);

The ServiceHelper can easily be extended to also provider other services.

Have fun!