dimanche 23 août 2015

Invoking a method through reflection in C# that takes a delegate as an Input in C#

I have an Employee Class Defined in a namespace and the snippet goes something like this

    namespace DelegatesSampleApplication
    {
        delegate  bool IsPromotable (Employee employee);
        class Program
        {
            public static void Main(string[] args)
            {
                List<Employee> empList = new List<Employee>();
                empList.Add(new Employee() { EmployeeId = 1, EmployeeName = "A", Salary = 7500, Experience = 2 });
                empList.Add(new Employee() { EmployeeId = 2, EmployeeName = "B", Salary = 11500, Experience = 6 });
                empList.Add(new Employee() { EmployeeId = 3, EmployeeName = "C", Salary = 14500, Experience = 5 });
                empList.Add(new Employee() { EmployeeId = 4, EmployeeName = "D", Salary = 10500, Experience = 7 });

                IsPromotable isPromotableObj = new IsPromotable(EnableToPromote);

                Employee EmployeeObj = new Employee();
                EmployeeObj.PromoteEmployees(empList, isPromotableObj);
            }

            public static bool EnableToPromote(Employee employee)
            {
                if (employee.Experience >= 5 && employee.Salary >= 10000)
                {
                    return true;
                }
                else
                    return false;
            }
        }

        class Employee
        {
            public int EmployeeId { get; set; }
            public string EmployeeName { get; set; }
            public int Salary { get; set; }
            public int Experience { get; set; }

            public void PromoteEmployees(List<Employee> employeeList, IsPromotable isPromotableObj)
            {

                foreach (Employee employee in employeeList)
                {
                    if (isPromotableObj(employee)) 
                    {
                        Console.WriteLine(" {0} will be promoted in the next R.P. Cycle ", employee.EmployeeName);
                    }
                }
                Console.ReadKey();
            }
        }
    }

Now from a separate class in a separate namespace via reflection I want to get the Class Type and all other type objects related to it. Also I want to invoke the PromoteEmployee() method. How do I do that ?

namespace ReflectionSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***************Loading External assembly*************");
            Assembly assembly = Assembly.LoadFrom(@"C:\Users\Chiranjib\Documents\visual studio 2012\Projects\DelegatesSampleApplication\DelegatesSampleApplication\bin\Debug\DelegatesSampleApplication.exe");
            Type employeeType = assembly.GetType("DelegatesSampleApplication.Employee"); //Gets the System.Type object for the Employee Class from the just loaded assembly with all it's dependencies

            object employeeInstance = Activator.CreateInstance(employeeType);//Create an instance of the Employee Class Type
            Console.WriteLine("***************Loading External assembly properties*************");
            PropertyInfo[] propertyInfoColl =  employeeType.GetProperties();
            foreach(var item in propertyInfoColl)
            {
                Console.WriteLine("Loaded Type Property Name {0} and default value {1}", item.Name, item.GetValue(employeeInstance, null));
            }
            Console.WriteLine("***************Setting External assembly propeties for the first instance*************");
            PropertyInfo employeeId = (PropertyInfo)employeeType.GetProperty("EmployeeId");
            employeeId.SetValue(employeeInstance, 1);
            Console.WriteLine("Employee Id Property value now set to " + employeeId.GetValue(employeeInstance,null));
            PropertyInfo employeeName = (PropertyInfo)employeeType.GetProperty("EmployeeName");
            employeeName.SetValue(employeeInstance, "A");
            Console.WriteLine("Employee Name Property value now set to " + employeeName.GetValue(employeeInstance, null));
            PropertyInfo salary = (PropertyInfo)employeeType.GetProperty("Salary");
            salary.SetValue(employeeInstance, 40000);
            Console.WriteLine("Salary Property value now set to " + salary.GetValue(employeeInstance, null));
            PropertyInfo experience = (PropertyInfo)employeeType.GetProperty("Experience");           
            experience.SetValue(employeeInstance, 3);
            Console.WriteLine("Experience Property value now set to " + experience.GetValue(employeeInstance, null));
            Console.WriteLine("***************Setting External assembly propeties for the second instance*************");
            object employeeInstance2 = Activator.CreateInstance(employeeType);
            PropertyInfo employeeId2 = (PropertyInfo)employeeType.GetProperty("EmployeeId");
            employeeId2.SetValue(employeeInstance2, 2);
            Console.WriteLine("Employee Id Property value now set to " + employeeId2.GetValue(employeeInstance2, null));
            PropertyInfo employeeName2 = (PropertyInfo)employeeType.GetProperty("EmployeeName");
            employeeName2.SetValue(employeeInstance2, "B");
            Console.WriteLine("Employee Name Property value now set to " + employeeName2.GetValue(employeeInstance2, null));
            PropertyInfo salary2 = (PropertyInfo)employeeType.GetProperty("Salary");
            salary2.SetValue(employeeInstance2, 50000);
            Console.WriteLine("Salary Property value now set to " + salary2.GetValue(employeeInstance2, null));
            PropertyInfo experience2 = (PropertyInfo)employeeType.GetProperty("Experience");
            experience2.SetValue(employeeInstance2, 6);
            Console.WriteLine("Experience Property value now set to " + experience2.GetValue(employeeInstance2, null));
            Console.WriteLine("***************Creating an array list that will hold these employee instances***************");
            List<Object> employeeInstanceList = new List<object>();
            employeeInstanceList.Add(employeeInstance);
            employeeInstanceList.Add(employeeInstance2);
            Console.WriteLine("***************Invoking External assembly methods*************");
            var agrsDel = new Object[] {(employeeInstance) => return employeeInstance};

            dynamic value = employeeType.InvokeMember("PromoteEmployees", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, employeeInstance, new Object[] {employeeInstanceList,args})});
            Console.ReadKey();

        }
    }
}

But the errors I am getting are for agrsDel it cannot covert a lambda expression to an object and secondly object does not contain a definition for employeeId. What am I missing ? Please help me. Thanks a lot.





Aucun commentaire:

Enregistrer un commentaire