4

Let's say I have a class Abc:

class Abc {
}

and that I'd like to externally add some method m() to it. I guess it's probably possible to do this, although I am not sure how. Assuming it is possible to do that, let's then say Abc does have, from now on, a m() method.

Now, imagine I have other class Def:

class Def {
    public void x(Abc abc) {
        abc.m();
    }
}

Would this code run with PostSharp? To the more distracted reader, the problem with this is that in a standard C# class program, our compiler might not know the Abc class has a m() method.

My gut feeling is that this wouldn't work with PostSharp. Am I mistaken?

devoured elysium
  • 101,373
  • 131
  • 340
  • 557

2 Answers2

3

(Maybe you can use the DLR to accomplish if my PostSharp solutions aren't sufficient?)

Yes you can. You would use introducemember attribute in an instance scoped aspect. Your best bet is to implement an interface using postshsrp then reference your target class as that interface to expose the method. You can also use Post.Cast<>() to access it at design time.

Here are two methods to do this. The first is via an interface, the second is using stubs.

Method 1 - Interface

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            var cc = Post.Cast<Customer, ISomething>(c);

            cc.SomeMethod();
        }
    }

    public interface ISomething
    {
        void SomeMethod();
    }

    [AddMethodAspect]
    public class Customer
    {

    }

    [Serializable]
    [IntroduceInterface(typeof(ISomething))]
    public class AddMethodAspect : InstanceLevelAspect, ISomething
    {

        #region ISomething Members

        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }

        #endregion
    }

Method 2 - stubs

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            c.SomeMethod();
        }
    }

    [AddMethodAspect]
    public class Customer
    {
        public void SomeMethod() { }

    }

    [Serializable]
    public class AddMethodAspect : InstanceLevelAspect
    {
        [IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }
    }

More Info Just in case there are some issues with using the Cast<>() function, it doesn't do an actual cast. The compiled result looks like:

private static void Main(string[] args)
        {
            Customer c = new Customer();
            ISomething cc = c;
            cc.SomeMethod();
        }
Dustin Davis
  • 14,482
  • 13
  • 63
  • 119
0

You can do it if the class is in a different assembly.

On the other hand, if the classes are in the same module, then you are right, the C# compiler won't compile it. Why not implement m() like this in C#, then replace the implementation with PostSharp?

class Abc
{
   public void m()
   {
      throw new NotImplementedException ();
   }
}

Edit:

What if you put m() in an interface, then use PostSharp to implement the interface on your class? Then you can call the method by casting to that interface.

interface IM
{
   void m();
}

class Def {
    public void x(Abc abc) {
       if (abc is IM)
        ((IM) abc).m();
    }
}
agent-j
  • 27,335
  • 5
  • 52
  • 79
  • 1
    Because then it'd defeat the whole purpose of having my cross-cutting concerns only in the aspects and not in the classes themselves! Adding/removing concerns would then imply having to change all the classes. – devoured elysium Jul 01 '11 at 15:08
  • How are you cross-cutting concerns if you're calling a method directly? What if you put `m()` in an interface, then use PostSharp to implement the interface on your class? Then you can call the method by casting to that interface. – agent-j Jul 01 '11 at 15:11
  • I don't see what is the problem with having a method call from an aspect. Imagine a ApplyBonus aspect, which has all the logic associated with bonus in a banking system. – devoured elysium Jul 01 '11 at 15:34