Search code examples
aoppostsharp

Can you apply aspects in PostSharp without using attributes?


I know with Castle Windsor, you can register aspects (when using method interception in Windsor as AOP) using code instead of applying attributes to classes. Is the same possible in Postsharp? It's a preference things, but prefer to have aspects matched to interfaces/objects in one place, as opposed to attributes all over.

Update: Curious if I can assign aspects to interfaces/objects similiar to this:

container.Register(
        Component
        .For<IService>()
        .ImplementedBy<Service>()
        .Interceptors(InterceptorReference.ForType<LoggingAspect>()).Anywhere
   );

If you could do this, you would have the option of NOT having to place attributes on assemblies/class/methods to apply aspects. I can then have one code file/class that contains which aspects are applied to which class/methods/etc.


Solution

  • Yes. You can either use multicasting (http://www.sharpcrafters.com/blog/post/Day-2-Applying-Aspects-with-Multicasting-Part-1.aspx , http://www.sharpcrafters.com/blog/post/Day-3-Applying-Aspects-with-Multicasting-Part-2.aspx) or you can use aspect providers (http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-12-e28093-Aspect-Providers-e28093-Part-1.aspx , http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-13-e28093-Aspect-Providers-e28093-Part-2.aspx).

    Example:

        using System;
        using PostSharp.Aspects;
        using PostSharp.Extensibility;
    
        [assembly: PostSharpInterfaceTest.MyAspect(AttributeTargetTypes = "PostSharpInterfaceTest.Interface1", AttributeInheritance = MulticastInheritance.Multicast)]
    
        namespace PostSharpInterfaceTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Example e = new Example();
                Example2 e2 = new Example2();
                e.DoSomething();
                e2.DoSomething();
                Console.ReadKey();
            }
        }
    
        class Example : Interface1
        {
    
            public void DoSomething()
            {
                Console.WriteLine("Doing something");
            }
        }
    
        class Example2 : Interface1
        {
    
            public void DoSomething()
            {
                Console.WriteLine("Doing something else");
            }
        }
    
        interface Interface1
        {
            void DoSomething();
        }
    
        [Serializable]
        class MyAspect : OnMethodBoundaryAspect
        {
            public override void OnEntry(MethodExecutionArgs args)
            {
                Console.WriteLine("Entered " + args.Method.Name);
            }
        }
    }
    

    I recommend that if you have complex requirements for determining which types get certain aspects that you consider creating an aspect provider instead.