Xamarin Forms Free AOP Library

dinobuljubasicdinobuljubasic USUniversity ✭✭
edited November 10 in Xamarin.Forms

I am looking to implement logging functionality to my Xamarin.Forms application.

I heard about MetroLog which seem to be interesting; however, I dont like the fact that a clean method like in example below gets cluttered with code that makes this method literally "polluted". In addition, it violates KISS, 10/100, SRP, .... principles:

public void DoSomething()
{
  Logger.Log("DoSomething - start");

  try
  {
     // do something here and possible do more logging
  } 
  catch(Exception ex)
  {
     Logger.Log("DoSomething threw exception: {0}", ex.Message);
  }

  Logger.Log("DoSomething - end");
}

This pollutes the code and violates the principles I mentioned above. This method should really look like this

public void DoSomething()
{
   // do something here
}

Then I read something about AOP (Aspect Oriented Programming) in which case, all the logging calls could be moved to a separate aspect class LoggerAspect and the method above could be used like:

[LoggerAspect]
public void DoSomething()
{
   // do something here
}

Has anyone used any free Xamarin.Forms friendly AOP library? Something like PostSharp (which unfortunately is not free and not Xamarin.Forms friendly)?

Can you recommend one?

Answers

  • ChaseFlorellChaseFlorell CAInsider, University mod

    We use Fody with the MethodDecorator with great success. The only downside is that you need to use Fody 1.x as V2 isn't supported on MethodDecorator and the library currently isn't being maintained.

    How it works.

    I have an Attribute called AnalyticsAttribute. I decorate all the methods that I want tracked as follows.

    public class Sample {
        [Analytics("Optional Description")]
        public void Method()
        {
            Debug.WriteLine("Your Code");
        }
    }
    

    the result after Fody is done is something like

    public class Sample {
        public void Method(int value) {
            InterceptorAttribute attribute =
                (InterceptorAttribute) Activator.CreateInstance(typeof(InterceptorAttribute));
    
            // in c# __methodref and __typeref don't exist, but you can create such IL
            MethodBase method = MethodBase.GetMethodFromHandle(__methodref (Sample.Method),
                                                               __typeref (Sample));
    
            object[] args = new object[1] { (object) value };
    
            attribute.Init((object)this, method, args);
    
            attribute.OnEntry();
            try {
                Debug.WriteLine("Your Code");
                attribute.OnExit();
            }
            catch (Exception exception) {
                attribute.OnException(exception);
                throw;
            }
        }
    }
    

    https://github.com/Fody/MethodDecorator

  • VovaKamishnikovVovaKamishnikov USMember ✭✭

    I use PropertyChanged.Fody
    I think it's worth to see mradvice

  • dinobuljubasicdinobuljubasic USUniversity ✭✭

    @ChaseFlorell said:
    We use Fody with the MethodDecorator with great success. The only downside is that you need to use Fody 1.x as V2 isn't supported on MethodDecorator and the library currently isn't being maintained.

    How it works.

    I have an Attribute called AnalyticsAttribute. I decorate all the methods that I want tracked as follows.

    public class Sample   {
      [Analytics("Optional Description")]
      public void Method()
      {
          Debug.WriteLine("Your Code");
      }
    }
    

    the result after Fody is done is something like

    public class Sample {
      public void Method(int value) {
          InterceptorAttribute attribute =
              (InterceptorAttribute) Activator.CreateInstance(typeof(InterceptorAttribute));
    
          // in c# __methodref and __typeref don't exist, but you can create such IL
          MethodBase method = MethodBase.GetMethodFromHandle(__methodref (Sample.Method),
                                                             __typeref (Sample));
    
          object[] args = new object[1] { (object) value };
    
          attribute.Init((object)this, method, args);
    
          attribute.OnEntry();
          try {
              Debug.WriteLine("Your Code");
              attribute.OnExit();
          }
          catch (Exception exception) {
              attribute.OnException(exception);
              throw;
          }
      }
    }
    

    https://github.com/Fody/MethodDecorator

    I dont understand why do you use Debug.WriteLine in Method() method in your example? Isn't it the whole point to not to have pulute your code with statements like that, or Loger.Log...?

  • dinobuljubasicdinobuljubasic USUniversity ✭✭

    @VovaKamishnikov said:
    I use PropertyChanged.Fody
    I think it's worth to see mradvice

    would you mind providing bit more info or a simple example please?

  • VovaKamishnikovVovaKamishnikov USMember ✭✭
    edited November 14

    would you mind providing bit more info or a simple example please?

    Yes, of course.
    See the links for more details.
    https://github.com/ArxOne/MrAdvice
    wiki
    https://github.com/ArxOne/MrAdvice/wiki/ImplementingAdvices

  • ChaseFlorellChaseFlorell CAInsider, University mod

    @VovaKamishnikov said:
    I use PropertyChanged.Fody
    I think it's worth to see mradvice

    PropertyChanged.Fody does not provide AOP type Analytics. It just rewrites auto-properties into get;set; with RaisePropertyChanged bits.

    @dinobuljubasic said:
    I dont understand why do you use Debug.WriteLine in Method() method in your example? Isn't it the whole point to not to have pulute your code with statements like that, or Loger.Log...?

    In mobile development you cannot JIT inject your Logger because of iOS's required of everything being AOT. What Fody.MethodDecorator does is injects the code at build time so that you don't need to see it or deal with it at development time.

    The Debug.WriteLine stuff is out of their example code. It will actually be whatever you want it to be depending on how you write your custom attribute. The way I do it is I capture the method name and the class name on Init() and then use my own Analytics proxy bits that all me to inject my analytics provider.

  • dinobuljubasicdinobuljubasic USUniversity ✭✭

    @ChaseFlorell said:

    @VovaKamishnikov said:
    I use PropertyChanged.Fody
    I think it's worth to see mradvice

    PropertyChanged.Fody does not provide AOP type Analytics. It just rewrites auto-properties into get;set; with RaisePropertyChanged bits.

    @dinobuljubasic said:
    I dont understand why do you use Debug.WriteLine in Method() method in your example? Isn't it the whole point to not to have pulute your code with statements like that, or Loger.Log...?

    In mobile development you cannot JIT inject your Logger because of iOS's required of everything being AOT. What Fody.MethodDecorator does is injects the code at build time so that you don't need to see it or deal with it at development time.

    The Debug.WriteLine stuff is out of their example code. It will actually be whatever you want it to be depending on how you write your custom attribute. The way I do it is I capture the method name and the class name on Init() and then use my own Analytics proxy bits that all me to inject my analytics provider.

    I am bit concerned that the Foody library is not maintained any more and cannot be updated

  • ChaseFlorellChaseFlorell CAInsider, University mod

    @dinobuljubasic said:
    I am bit concerned that the Foody library is not maintained any more and cannot be updated

    Fody is maintained, it's the MethodDecorator that is currently not. We're working on trying to get Simon to push the latest build that supports Fody 2.0, from there it will need a new maintainer. That said however, it works great as is.

Sign In or Register to comment.