Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write function decorator in c# like python

Tags:

c#

.net-4.5

I have worked on python for a while and returned to c# for a project. So I used to python language and that forces me think like a python programmer and i like this!

The question i want to ask how can i create a method that called after its decarator ?

Python decorator syntax:

def p_decorate(func):
   def func_wrapper(name):
       return "<p>{0}</p>".format(func(name))
   return func_wrapper

@p_decorate
def get_text(name):
   return "lorem ipsum, {0} dolor sit amet".format(name)

I have googled but found only .Net Attributes And it couldn't helped me.

Sample code but i want to write my own AuthorizationAttribute class.

public class RestrictAccessToAssignedManagers : AuthorizationAttribute
{
    protected override AuthorizationResult IsAuthorized(System.Security.Principal.IPrincipal principal, AuthorizationContext authorizationContext)
    {
        EmployeePayHistory eph = (EmployeePayHistory)authorizationContext.Instance;
        Employee selectedEmployee;
        Employee authenticatedUser;

        using (AdventureWorksEntities context = new AdventureWorksEntities())
        {
            selectedEmployee = context.Employees.SingleOrDefault(e => e.EmployeeID == eph.EmployeeID);
            authenticatedUser = context.Employees.SingleOrDefault(e => e.LoginID == principal.Identity.Name);
        }

        if (selectedEmployee.ManagerID == authenticatedUser.EmployeeID)
        {
            return AuthorizationResult.Allowed;
        }
        else
        {
            return new AuthorizationResult("Only the authenticated manager for the employee can add a new record.");
        }
    }
}

[RestrictAccessToAssignedManagers]
public void InsertEmployeePayHistory(EmployeePayHistory employeePayHistory)
{
    if ((employeePayHistory.EntityState != EntityState.Detached))
    {
        this.ObjectContext.ObjectStateManager.ChangeObjectState(employeePayHistory, EntityState.Added);
    }
    else
    {
        this.ObjectContext.EmployeePayHistories.AddObject(employeePayHistory);
    }
}

Sample code from MSDN

like image 607
RockOnGom Avatar asked Jul 13 '16 14:07

RockOnGom


1 Answers

Often that is used in Aspect Oriented Programming, two popular libraries to do it are PostSharp and Fody.

Here is a example with PostSharp of your original python example.

using System;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Extensibility;

namespace SandboxConsole
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine(GetText("Test"));
            Console.ReadLine();
        }

        [Decorate]
        public static string GetText(string name)
        {
            return String.Format("lorem ipsum, {0} dolor sit amet", name);
        }
    }

    [Serializable]
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class DecorateAttribute : MethodInterceptionAspect
    {
        public override bool CompileTimeValidate(MethodBase method)
        {
            if (!((MethodInfo)method).ReturnType.IsAssignableFrom(typeof(string)))
            {
                Message.Write(SeverityType.Error, "CUSTOM01", "Can not apply [Decorate] to method {0} because it does not retun a type that is assignable from string.", method);
                return false;
            }
            return true;
        }

        public override void OnInvoke(MethodInterceptionArgs args)
        {
            args.Proceed();
            args.ReturnValue = String.Format("<p>{0}</p>", args.ReturnValue);
        }
    }
}
like image 109
Scott Chamberlain Avatar answered Oct 16 '22 07:10

Scott Chamberlain