Search code examples
c#postsharp

PostSharp injecting dependency to aspect


Is it possible to inject dependency into PostSharp aspect? I'd like to create NavigateBackAspect - something like that:

[PSerializable]
class NavigateBackAspect : OnMethodBoundaryAspect
{
    private readonly INavigationService _navigationService;

    public NavigateBackAspect(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        base.OnExit(args);
        var viewModel = args.Instance as Shared.ViewModel.ViewModel;

        if (viewModel != null)
        {
            viewModel.Dispose();
            _navigationService.GoBack();
        }
    }
}

However I've read that constructor/parameter injection is not possible because constructor is called just once after compilation. Are there any workarounds?


Solution

  • This kind of thing is not possible mainly because attributes in general and aspects in particular can only have constant expressions in the constructor.

    The constructor is called once per aspected target during compilation time. After this happens, the aspect is serialized (along with any internal data it may contain). It is deserialized during runtime, which means the constructor is not called at all. But there is no reason for it to be called; attribute constructors can only contain constant data that isn't liable to change. See about aspect lifetime here.

    However, every aspected target still has its own instance of the aspect. This means you can do this during runtime initialization. You have a few options:

    1. Supply a string key parameter to the constructor, and then during runtime look up the appropriate object using the key (from a shared dictionary).
    2. Rely on the aspected type to have a property or field containing the object, and access it through reflection. It's recommended you do this during runtime initialization because reflection can cause performance problems.