Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Make [assembly: Attribute] work with virtual methods that don't have an override #222

Open
Jinjinov opened this issue Aug 5, 2023 · 2 comments

Comments

@Jinjinov
Copy link

Jinjinov commented Aug 5, 2023

Thank you for your great library! I am using it in my https://github.com/Jinjinov/BlazorWasmProfiler

Describe the solution you'd like

protected virtual void OnParametersSet() is a method defined in Microsoft.AspNetCore.Components.ComponentBase.
If I define protected override void OnParametersSet() in a .razor file (Blazor component) then [assembly: Attribute] works.

I would like [assembly: Attribute] to work with every Blazor component (every Type derived from Microsoft.AspNetCore.Components.ComponentBase) even if there is no protected override void OnParametersSet() in a .razor file.

Describe alternatives you've considered

I tried using a Microsoft.CodeAnalysis.ISourceGenerator to add protected override void OnParametersSet() to every Blazor component, but it is not possible to chain source generators. Because all source generators run in parallel, the Razor source generator that generates C# classes from razor files was running in parallel with my source generator (which tried to find types derived from Microsoft.AspNetCore.Components.ComponentBase and could not find any).

Additional context

I also tried using Mono.Cecil to add protected virtual void OnParametersSet() to the Blazor assembly, but changing the dll file in \bin\Debug\net7.0 doesn't help. Then I also tried changing the dll file in \bin\Debug\net7.0\wwwroot\_framework but it still doesn't work. Then I tried changing the file in \obj\Debug\net7.0 but the build crashes.

Do you have any suggestions how I can make it work?

@pamidur
Copy link
Owner

pamidur commented Oct 6, 2023

Sorry for delay,
this is interesting feature request that was actually requested several times by now.
Could you please drop a source code sample where it does not work with comments where it should work? It would help immensely!

@Jinjinov
Copy link
Author

Jinjinov commented Oct 8, 2023

Third party NuGet Assembly1

namespace Assembly1;

public class Base
{
    public virtual Foo()
    {
    }
}

My project Assembly2

MethodTimerAttribute.cs

using AspectInjector.Broker;
using System;

namespace Assembly2
{
    [Aspect(Scope.Global)]
    [Injection(typeof(MethodTimerAttribute))]
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class MethodTimerAttribute : Attribute
    {
        [Advice(Kind.Before)]
        public void OnEntry([Argument(Source.Name)] string methodName, [Argument(Source.Type)] Type declaringType)
        {
            Console.WriteLine($"Before {declaringType}.{methodName}");
        }

        [Advice(Kind.After)]
        public void OnExit([Argument(Source.Name)] string methodName, [Argument(Source.Type)] Type declaringType)
        {
            Console.WriteLine($"After {declaringType}.{methodName}");
        }
    }
}

Program.cs

namespace Assembly2;

[assembly: MethodTimer]

var ok = new DerivedMethodTimerWorking();
ok.Foo(); // MethodTimer is working

var notOk = new DerivedMethodTimerNotWorking();
notOk.Foo();  // MethodTimer is not working

Derived.cs

namespace Assembly2;

class DerivedMethodTimerWorking : Assembly1.Base
{
    public override Foo()
    {
    }
}

class DerivedMethodTimerNotWorking : Assembly1.Base
{
    public Bar()
    {
    }
}

I would like that MethodTimer would work in DerivedMethodTimerNotWorking.Foo even though it is not overriden in Assembly2 and the virtual method source is in NuGet Assembly1

What I tried to do was to add public override Foo() to DerivedMethodTimerNotWorking with Mono.Cecil but it doesn't compile / build in my Blazor project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants