Open Closed

Extending razor components - Blazor #1148


User avatar
0
Leonardo.Willrich created

ABP Framework version: v4.2.3 rc.1 UI type: Blazor DB provider: EF Core Tiered (MVC) or Identity Server Separated (Angular): yes / no Exception message and stack trace: Steps to reproduce the issue:

Hi,

If I have to extend the component DefaultLayout from Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout, do I need to rewrite the whole markups elements or it will be inherited?

I was not able to inherited the elements, I had to rewrite them again. I don't want to do that because I just want to override the method OnInitialize().

My new components:

@using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout
@inherits DefaultLayout
@using Volo.Abp.Ui.Branding
@using Volo.Abp.BlazoriseUI.Components
@using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout.MainHeader
@using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout.MainFooter
@inject IBrandingProvider BrandingProvider
<MainHeader />
<div class="lp-content h-100">
    <PageAlert />
    @Body
    <UiMessageAlert />
    <UiNotificationAlert />
</div>
<MainFooterComponent />

That is the code that I don't want to have to rewrite. I would like that would be inherited from DefaultLayout as specified by @inherited DefaultLayout

Code-behind:

using Microsoft.AspNetCore.Components;
using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout;
using Volo.Abp.DependencyInjection;

namespace TVD_Holdings_Ltd.AvalancheOCP.Blazor.Components.ApplicationLayout
{
    [ExposeServices(typeof(DefaultLayout))]
    [Dependency(ReplaceServices = true)]
    public partial class DefaultLayoutExtension 
    {

        [Inject] IConfiguration Configuration { get; set; }
        [Inject] IAlertManager _alertManager { get; set; }
        private HubConnection hubConnection;

        protected override async Task OnInitializedAsync()
        {
            // Do something
        }
    }
}


4 Answer(s)
  • User Avatar
    0
    mladen.macanovic created

    This is how Blazor works.

    You cannot inherit razor code part. You can only inherit from the class type. What I mean my that? Well, you must know what razor file represents in Blazor component. Basically, it is a RenderFragment that is rendering (in pseudo code).

    override void Render()
    {
       // render elements
    }
    

    Once compiled it is just a regular Render method. That is why you can't inherit it. You must write the implementation again.

    Regerding you problem with OnInitializedAsync, I think you can do that. Instead of inherting both .razor and .cs, inherit only the class part.

    using Microsoft.AspNetCore.Components;
    using System;
    using System.Threading.Tasks;
    using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout;
    using Volo.Abp.DependencyInjection;
    
    namespace TVD_Holdings_Ltd.AvalancheOCP.Blazor.Components.ApplicationLayout
    {
        [ExposeServices(typeof(DefaultLayout))]
        [Dependency(ReplaceServices = true)]
        public class DefaultLayoutExtension : DefaultLayout
        {
    
            [Inject] IConfiguration Configuration { get; set; }
            [Inject] IAlertManager _alertManager { get; set; }
            private HubConnection hubConnection;
    
            protected override async Task OnInitializedAsync()
            {
                // Do something
            }
        }
    }
    
  • User Avatar
    0
    Leonardo.Willrich created

    Hi mladen.macanovic,

    Thank you for your answer. I got your point and I am rewriting the razor part as well.

    I've tried your suggestion with MainHeader component, only inheriting the class part, but that doesn't work, see below:

    Code:

    using System;
    using System.Threading.Tasks;
    using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout.MainHeader;
    using Volo.Abp.DependencyInjection;
    
    namespace TVD_Holdings_Ltd.AvalancheOCP.Blazor.Components.Layout
    {
        [ExposeServices(typeof(MainHeader))]
        [Dependency(ReplaceServices = true)]
        public class MainHeaderExtension : MainHeader
        {
            protected override async Task OnInitializedAsync()
            {
                Console.WriteLine("MainHeader Init");
            }
        }
    }
    

    Error:

    My only concern overriding the .razor and .razor.cs is updating the framework and getting conflit or missing some changes due to overriden files.

  • User Avatar
    0
    mladen.macanovic created

    I tried the same logic in Blazorise code and it working fine. Might be something in ABP that is interfering maybe. I will need to investigate more and get back to you.

    In the meantime just use both .razor and .razor.cs. While not the pretiest, it is a working solution.

  • User Avatar
    0
    Leonardo.Willrich created

    Hi mladen,

    Please, don't prioritize that! I have a workaround and I end up adding one more component to the layout anyway to show a modal message. I'll close this thread, I appreciate your help and explanation.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on June 20, 2025, 11:20