Search code examples
c#aopcilfody

Pass parameters to the constructor in Method Decorator Fody


This is my code of the Attribute Class that extends IMethodDecorator Interface

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Field)]
public class LogAttribute : Attribute, IMethodDecorator
{
    ILogger log = Logger.Factory.GetLogger<Logger>();
    String methodName;


    public LogAttribute() {
    }

    public void Init(object instance, MethodBase method, object[] args)
    {
        methodName = method.Name;
    }

    public void OnEntry()
    {
        Console.WriteLine(methodName);
        log.Debug(methodName);
    }

    public void OnExit()
    {
        Console.WriteLine("Exiting Method");
    }

    public void OnException(Exception exception)
    {
        Console.WriteLine("Exception was thrown");
    }

}

I want to be able to use this as

[log("some logmessage")]
void method() 
{
// some code  
}

Any ideas ? I am using Method Decorator Fody package.


Solution

  • So I found a solution to my problem.

    Basically I modified my class like -

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Field)]
    public class LogAttribute : Attribute, IMethodDecorator
    {
        ILogger log = Logger.Factory.GetLogger<Logger>();
        String methodName;
    
        public String logMessage { get; set; }
    
        private Lazy<IEnumerable<PropertyInfo>> _properties;
        public MethodBase DecoratedMethod { get; private set; }
    
        public LogAttribute() {
            this._properties = new Lazy<IEnumerable<PropertyInfo>>(() =>
             this.GetType()
                 .GetRuntimeProperties()
                 .Where(p => p.CanRead && p.CanWrite));
        }
    
    
        public void Init(object instance, MethodBase method, object[] args)
        {
            this.UpdateFromInstance(method);
            methodName = method.Name;
        }
    
        public void OnEntry()
        {
            log.Debug("Inside" + methodName);
            log.Debug(logMessage);
        }
    
        public void OnExit()
        {
            Console.WriteLine("Exiting Method");
        }
    
        public void OnException(Exception exception)
        {
            Console.WriteLine("Exception was thrown");
        }
    
        private void UpdateFromInstance(MethodBase method)
        {
            this.DecoratedMethod = method;
            var declaredAttribute = method.GetCustomAttribute(this.GetType());
    
            foreach (var property in this._properties.Value)
                property.SetValue(this, property.GetValue(declaredAttribute));
    
        }
    
    }
    

    Now I can use custom attribute like

     [Log(logMessage = "This is Debug Message")]