ArxOne / MrAdvice

.NET aspect weaver (build task under NuGet package)
MIT License
308 stars 45 forks source link

Override assembly level attributes #206

Closed jorgenbosman closed 2 months ago

jorgenbosman commented 2 months ago

I have an attibute which accepts some constructor parameters:

   internal class MyAttribute : Attribute, IMethodAsyncAdvice
   {
       int increment;
       public static int count = 0;

       public MyAttribute(int increment)
       {
           this.increment = increment;
       }

       public async Task Advise(MethodAsyncAdviceContext context)
       {
           Console.WriteLine($"Adding {increment} to Counter.count");
           count += increment;
           await context.ProceedAsync();
       }
   }

Then I use this attribute at assembly level, but for one method, I want to override the attribute constructor value:

using MrAdviceTest;

[assembly: My(1)]

namespace MrAdviceTest
{
    internal class Program
    {
        [My(2)]
        public static void Method1()
        {
        }

        static void Main(string[] args)
        {
            Console.WriteLine($"Before: counter={MyAttribute.count}");
            Method1();
            Console.WriteLine($"After: counter={MyAttribute.count}");
        }
    }
}

I would have expected the output to be:

Adding 1 to Counter.count
Before: counter=1
Adding 2 to Counter.count
After: counter=3

But in reality it is:

Adding 1 to Counter.count
Before: counter=1
Adding 1 to Counter.count
Adding 2 to Counter.count
After: counter=4

So it seems that adding the [My(2)] attribute on method level does not override the attribute on assembly level, but adds it to the list of attrbutes...

I also tested with 1 instead of 2:

using MrAdviceTest;

[assembly: My(1)]

namespace MrAdviceTest
{
    internal class Program
    {
        [My(1)]
        public static void Method1()
        {
        }

        static void Main(string[] args)
        {
            Console.WriteLine($"Before: counter={MyAttribute.count}");
            Method1();
            Console.WriteLine($"After: counter={MyAttribute.count}");
        }
    }
}

And then the output is:

Adding 1 to Counter.count
Before: counter=1
Adding 1 to Counter.count
After: counter=2

Which is expected...

picrap commented 2 months ago

Agreed! And thank you.