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

In a Advice method with Kind.Before and Target.Constructor, accessing mixed-in properties injected into a class containing an explicit constructor causes NullReferenceError. #221

Closed
amguilmet opened this issue Jul 13, 2023 · 4 comments
Labels

Comments

@amguilmet
Copy link

amguilmet commented Jul 13, 2023

Environment (please complete the following information):

  • OS: windows
  • Framework: net 7
  • Type of application: console
  • Version of AspectInjector 2.8.2

Describe the bug
When trying to use a Scope.PerInstance Aspect to mix in an interface property, any attempt to access that property in an Advice method will throw a NullReferenceException when the Advice method uses both Kind.Before and Target.Constructor and the class upon which the aspect is applied has an explicit constructor.
There are a few possible workarounds I've found so far, but they all have drawbacks in my case. You could:
-omit the explicit constructor, but that's not feasible in classes that use DI with constructor injection.
-use Kind.After, but that's not desirable in some cases eg. when trying use aspects to track object lifetimes.
-use Scope.Global, but that makes mixin properties shared across all class instances.

To Reproduce

using AspectInjector.Broker;
namespace MixinTest;

internal class Program
{
    static void Main(string[] args)
    {
        using var instance = new Trackable();
        using var instance2 = new Trackable();
    }
}

[TrackLifetime]
public class Trackable : IDisposable
{
    public Trackable()
    {
        Console.WriteLine("Explicit Constructor");
    }

    public void Dispose()
    {
    }
}

public interface ITrackLifetime
{
    Guid Id { get; set; }
}

[Aspect(Scope.PerInstance)]
[Injection(typeof(TrackLifetime))]
[Mixin(typeof(ITrackLifetime))]
public class TrackLifetime : Attribute, ITrackLifetime
{
    public Guid Id { get; set; }

    [Advice(Kind.Before, Targets = Target.Constructor)]
    public void TrackableConstructor(
        [Argument(Source.Instance)] object instance)
    {
        Id = Guid.NewGuid(); //Exception occurs here
        Console.WriteLine($"Constructing {instance.GetType()} : {Id}");
    }

    [Advice(Kind.After, Targets = Target.Method)]
    public void TrackableDisposal(
        [Argument(Source.Name)] string name,
        [Argument(Source.Instance)] object instance)
    {
        if (name == nameof(IDisposable.Dispose))
            Console.WriteLine($"Disposed {instance.GetType()} : {Id}");

    }
}
@amguilmet amguilmet added the bug label Jul 13, 2023
@amguilmet amguilmet changed the title Accessing mixed in properties from a PerInstance scope injected into a class with an explicit constructor causes NullReferenceError. In a Advice method with Kind.Constructor, accessing mixed-in properties injected into a class containing an explicit constructor causes NullReferenceError. Jul 13, 2023
@amguilmet amguilmet changed the title In a Advice method with Kind.Constructor, accessing mixed-in properties injected into a class containing an explicit constructor causes NullReferenceError. In a Advice method with Kind.Before and Target.Constructor, accessing mixed-in properties injected into a class containing an explicit constructor causes NullReferenceError. Jul 13, 2023
@pamidur
Copy link
Owner

pamidur commented Jul 13, 2023 via email

@pamidur
Copy link
Owner

pamidur commented Jul 14, 2023

for some reason aspect calls are attemted even before the aspects are initialized
image

pamidur added a commit that referenced this issue Jul 14, 2023
@pamidur
Copy link
Owner

pamidur commented Jul 14, 2023

please let me know if 2.8.3-pre1 fixes it for you!

@amguilmet
Copy link
Author

Works wonderfully!

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

No branches or pull requests

2 participants