Hello Everyone:
Are we not supporting dependency injection in theme objects yet? I'm having issues trying every way I've done prior to include the INavigationManager in a theme object, but I can't find a way to both get it to compile and also not throw exceptions at runtime.
In short, after adding the Nuget references to <code>DotNetNuke,Core</code>, <code>.Abstractions</code>, and .<code>DependencyInjection</code>, the following code snippets that normally would work do not.
using DotNetNuke.Abstractions; private readonly INavigationManager _NavigationManager; public User() { this._NavigationManager = this.DependencyProvider.GetRequiredService(); }
In the snippet above, I can't find a way to get <code>DependencyProvider</code> to resolve. I've tried with/without this. and <code><INavagationManager></code> to no avail. Without in some way to initialize the <code>DependencyProvider</code> in the theme object, the <code>_NavigationManager</code> object is <code>null</code>.
When looking at the source code for SkinObjectBase, it looks like the base class doesn't include any references to dependency injection. Am I missing something obvious? 🤔
Oh, and I've also added the following to the C# class and csproj.
<code>using Microsoft.Extensions.DependencyInjection;</code>
<code><Reference Include="netstandard" /></code>
I just found a core theme object that's doing almost exactly what I'm doing, but I don't see any differences. 🤔
https://github.com/dnnsof...User.ascx.cs#L11-L35
I still can't get the <code>DependencyProvider</code> to resolve, even when using <code>Globals.</code>.
WebForms DI support will be available in DNN 10, which will support regular constructor injection without having to do any other tricks.
<code>Globals.DependencyProvider</code> is internal, so that's why the core skin object can use it but your skin object cannot.
Until DNN 10, you can use the following technique to get the DI scope for the request:
<code> using DotNetNuke.Abstractions; using DotNetNuke.Common.Extensions; private readonly INavigationManager _NavigationManager; public User() { IServiceScope currentScope = HttpContext.Current.GetScope(); IServiceProvider serviceProvider = scope.ServiceProvider; this._NavigationManager = serviceProvider.GetRequiredService<INavigationManager>(); } </code>
Posted By Brian Dukes on 1/14/2025 1:36 PM Until DNN 10, you can use the following technique to get the DI scope for the request: <code> using DotNetNuke.Abstractions; using DotNetNuke.Common.Extensions; private readonly INavigationManager _NavigationManager; public User() { IServiceScope currentScope = HttpContext.Current.GetScope(); IServiceProvider serviceProvider = scope.ServiceProvider; this._NavigationManager = serviceProvider.GetRequiredService<INavigationManager>(); } </code>
This was exactly what I needed... Thanks, Brian! 🥳💪🏽
Okay, so here we are a year later. v10 has been out for a while. I am interested in using the code versions of the new fluent CDF stuff in my skin. I don't want to use the skin objects because we generate a few different JS files sometimes and not others. So our auth.bundle.esm.js may or may not be there. So we like to wrap it in a utility/helper that calls System.IO.File.Exists().
So, I've added a partial to my theme and am including partials/preheader-cdf.ascx. My environment is DNN v10.02.01 and I really wanted to do the DI the new way. I did find the right interface, IClientResourceController. But no matter how many examples I found or things I read that seemed to be hinting that there was a new way in v10... I could not get it to work.
Here is what I do have working:
<%@ Import Namespace="Microsoft.Extensions.DependencyInjection" %> <%@ Import Namespace="DotNetNuke.Common.Extensions" %> <%@ Import Namespace="DotNetNuke.Abstractions" %> <%@ Import Namespace="DotNetNuke.Abstractions.ClientResources" %> <%@ Import Namespace="DotNetNuke.Web.Client.ResourceManager" %> <script runat="server"> private IClientResourceController _clientResourceController; protected override void OnLoad(EventArgs e) { base.OnLoad(e); AddJs(); // AddOpenGraph(); } private void AddJs() { // TODO get the v10 way working, this also works in v9 IServiceScope currentScope = HttpContext.Current.GetScope(); IServiceProvider serviceProvider = currentScope.ServiceProvider; this._clientResourceController = serviceProvider.GetRequiredService(); // TESTING Fluent CDF var cssAuth = _clientResourceController.CreateStylesheet("SkinAuth.css", PathNameAlias.SkinPath) .SetProvider(ClientResourceProviders.DnnFormBottomProvider) .SetPriority(FileOrder.Css.SkinCss) ; _clientResourceController.AddStylesheet(cssAuth); ...
So, anyone know what the DNN v10 way to do those first 3 lines under the // TODO?
If I wired up the code behind, is there an example somewhere of what that would look like?
These Forums are for the discussion of the open source CMS DNN platform and ecosystem.
For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:
Awesome! Simply post in the forums using the link below and we'll get you started.