Invoke abstract class method using reflection c# - c#

My external dll design looks like :
class Engineering
{
ProjectsCollection project {get;}
}
abstract class ProjectsCollection
{
public abstract Project Open(string path);
}
I'm able to proceed till getting the method info
MethodInfo info = type.GetMethod("Open");
How to invoke the method "Open"?

Reflection or not, you cannot invoke an abstract method, because there is nothing to invoke. Sure, you can write
info.Invoke(eng.project, new object[] {path});
but it will throw an exception unless eng.project is set to an object of a non-abstract class descendent from ProjectCollection, which implements the Open method:
class ProjectsCollectionImpl : ProjectsCollection {
public Project Open(string path) {
return ...
}
}
Engineering eng = new Engineering(new ProjectsCollectionImpl());
MethodInfo info = type.GetMethod("Open");
var proj = info.Invoke(eng.project, new object[] {path});

Just call Invoke!
info.Invoke(someObject, new object[] {"This is the parameter of the method"});
Simple as that!
The return value of Invoke will be the return value of Open, which should be a Project object.
From the docs:
Invokes the method or constructor represented by the current instance, using the specified parameters.
Oh, and you should know that someObject above is the object that you're calling the method on. You should always make it an instance of a concrete class! Don't give it null!

Related

Dynamically call a specific method on every other method call

I'm on .NET 4.8, under Windows Forms. I have a specific amount of declared methods inside a project, in various classes. And I would like that every method in these classes to call another specific method at the very start of each method execution. What I mean it's like If I manually add the required code at line number one inside each method body to call this other specific method.
Why I would like to do this?: I wrote a specific method that prints debug information on which I'm interested to know. This method includes info about the caller member, but it is not in any way limited to that kind of info.
Then, while I'm developing any application in Debug mode I would like to call this method automatically on every other method call in my project (inside property getter/setter too, if possible), and I'm just very curious to know if exists an alternative to the nightmare of writing/copying a thousand times the required instruction to call this specific method inside each method body in the project.
Exists a way to achieve this at runtime?. Maybe... writing an helper method that would be called once to retrieve all declared methods through Reflection and do code injection points in their method bodies?. Not sure how to do so, and not sure if that is viable anyways; maybe with Reflection.Emit as suggested in this answer?
And could this be achieved without depending on third party dependencies like Postsharp as suggested in this question?. Really using Postsharp is not a viable solution for me because I suppose the solution will consist to decorate with custom attributes every declared method in the project.
I also found this other suggestion but it's basically what I intend to avoid: manually add code changes to every method call in the project (in this case to replace the invocation code).
Some suggestions that I found like that last are not applicable to my scenario because I need to call this specific method INSIDE / FROM the method body of other methods in order to be able retrieve debug info of the current caller member including its parameters and values.
As an option, RealProxy may help. There's a nice article by Bruno Sonnino on this topic: Aspect-Oriented Programming : Aspect-Oriented Programming with the RealProxy Class.
Also you may be able to use AOP features of Unity (the DI framework) for this purpose. There's a nice article on this topic by Dino Esposito: Interceptors in Unity.
Using a weaving tool like Fody is also another option.
Creating proxy classes using Reflection.Emit could be another option.
Example - AOP using RealProxy
A LogAttribute which Has MethodExecuting and MethodExecuted and runs before and after methods
Using RealProxy, you can create a proxy for your class, so that when you call a method, the Invoke method of the proxy will run and you can run any logic there, for example you can run something before or after the actual method call.
In this example, I show how you can create a MethodFilterAttribute having two methods OnMethodExecuting and OnMethodExecuted, and then if you decorate your method with an attribute derived from this attribute, those methods will run before and after executing of the original method.
Looking into the code, you see you don't necessarily need the attributes, and attributes are just there as an extensibility point.
The usage of the code in this example is something like this:
var calc = CalculatorFactory.GetInstance();
var a = calc.Add(1, 2);
var b = calc.Subtract(1, 2);
Which produce the output:
Add executing.
Add executed.
Subtract executing.
Subtract executed.
Using statements
This is an attribute that could be used for methods. It has OnMethodExecuting and OnMethodExecuted methods, and when you get a proxy of your class, and run the methods, these two filter methods will be executed before and after the method which is decorated by this attribute:
using System;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Linq;
[AttributeUsage(AttributeTargets.Method)]
public class MethodFilterAttribute : Attribute
{
public int Order { get; set; }
public virtual void OnMethodExecuting(
MethodInfo methodInfo, object[] args) { }
public virtual void OnMethodExecuted(
MethodInfo methodInfo, object[] args, object result) { }
}
LogAttribute
An implementation of MethodFilterAttribute which performs log before and after method execution:
public class LogAttribute : MethodFilterAttribute
{
override public void OnMethodExecuting(
MethodInfo methodInfo, object[] args)
{
Console.WriteLine($"{methodInfo.Name} executing.");
}
override public void OnMethodExecuted(
MethodInfo methodInfo, object[] args, object result)
{
Console.WriteLine($"{methodInfo.Name} executed.");
}
}
The DynamicProxy class
Creates a proxy of your object, and if you run methods of the object, if the methdod is decorated with a method filter attribute, then OnActionExecuting and OnActionExecuted will run.
Looking into the code, you see you don't necessarily need the attributes, and attributes are just there as an extensibility point.
public class DynamicProxy<T> : RealProxy
{
private readonly T original;
public DynamicProxy(T original)
: base(typeof(T))
{
this.original = original;
}
public override IMessage Invoke(IMessage msg)
{
var methodCall = msg as IMethodCallMessage;
var methodInfo = methodCall.MethodBase as MethodInfo;
try
{
var filters = methodInfo.GetCustomAttributes<MethodFilterAttribute>();
if (filters.Any())
{
filters.OrderBy(x => x.Order).ToList()
.ForEach(f => f.OnMethodExecuting(methodInfo, methodCall.InArgs));
}
var result = methodInfo.Invoke(original, methodCall.InArgs);
if (filters.Any())
{
filters.OrderBy(x => x.Order).ToList()
.ForEach(f => f.OnMethodExecuted(methodInfo, methodCall.InArgs, result));
}
return new ReturnMessage(result, null, 0,
methodCall.LogicalCallContext, methodCall);
}
catch (Exception e)
{
return new ReturnMessage(e, methodCall);
}
}
}
ICalculator interface and Calculator class
Methods of Calculator are decorated with Log attribute, which means before and after execution of those methods, log will run.
Please note: In the implementation of the proxy we are looking for the attributes, using the interface. Also having the interface is necessary.
public interface ICalculator
{
[Log]
int Add(int x, int y);
[Log]
int Subtract(int x, int y);
}
public class Calculator : ICalculator
{
public int Add(int x, int y)
{
return x + y;
}
public int Subtract(int x, int y)
{
return x - y;
}
}
CalculatorFactory
The factory which returns a proxy instance of ICalculator:
public class CalculatorFactory
{
public static ICalculator GetInstance()
{
var original = new Calculator();
return new DynamicProxy<ICalculator>(original)
.GetTransparentProxy() as ICalculator;
}
}
Usage
Get an proxied instance of the interface using the factory and run methods:
var calc = CalculatorFactory.GetInstance();
var a = calc.Add(1, 2);
var b = calc.Subtract(1, 2);
Which produce the output:
Add executing.
Add executed.
Subtract executing.
Subtract executed.

Reflection attribute method

I have an asbtract class and I have classes that are devired from it. I have an attribute called PluginEventAttribute that works like so:
[PluginEventAttribute(PluginEvent.Load)]
public void OnLoad()
{
Log("Test Plugin loaded!");
}
I want my code to check if there is a method that uses that attribute, and if so, call it with custom parameters. How can I do that in C# winforms?
You just have to enumerate the instance methods and call the method if it has said attribute. Here's a working example (I hope I got your intent correctly) :
using System;
using System.Reflection;
class Program
{
class MyAttr : Attribute { }
abstract class Base { };
class Derived : Base
{
[MyAttr]
public void foo() { Console.WriteLine("foo"); }
public void bar() { Console.WriteLine("bar"); }
}
static void Main()
{
Base someInstance = new Derived();
foreach (var m in someInstance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
if (m.GetCustomAttribute(typeof(MyAttr)) != null)
{
m.Invoke(someInstance, null); // prints "foo"
}
}
Console.ReadLine();
}
}
You may change the null argument in the call to Invoke to the array of arguments you wish to pass to the function. The contents of that array must match the function signature.
This has nothing to do with WinForms. It's all about CLR runtime and its type system.
I don't know any way how you could "just do it".
You can check if a method M has an attribute A only if you have a MethodInfo object that describes that method (methodinfo.GetCustomAttributes())
You can get MethodInfos in several ways, but the easiest and most obvious is to get the Type object and ask it about its methods (type.GetMethod()/type.GetMethods()).
You can get a Type object in several ways too. If you have any object at hand, you can call its GetType() method. Or, you can ask an Assembly object (that describes a DLL or EXE) about the Types it defines. (..)
So, if you have a foo object that someone already created:
call foo.GetType()
loop over type.GetMethods()
call method.GetCustomAttributes(typeof(YourAttribute))
check if it was found
Now if you notice that it as been found, you will end up having a MethodInfo that matches a method with that attribute. The only thing left is to call that method with methodinfo.Invoke and to pass it both parameters and the foo object.
Situation gets tricky if you don't have a foo object that you want to scan for methods. You must get the whole assembly, scan all types, scan all their methods. You end up with matching MethodInfo again. But you don't have any object to call the method found upon. Either that method will need to be static (so callable without target object) or you will need to somehow get matching object, too.

How do I access a constructor with user input in C#

In my program I have multiple instances of a specific class Tracer (A1,B2,C3 etc). Using a listbox called tracerListBox, the user will determine which tracer they want to use.
Lets say each tracer has a constructor named family.
I know that if I wanted to access the family of, say, A1 I would simply type:
A1.family
However, I want to write code that accomplishes something like this:
tracerListBox.Text.family
Is there a way to pass a user-determined value to a constructor? I essentially want the user to determine which instance of Class Tracer to use and then use that information to pull all of the information about that specific tracer.
Thanks in advance for any assistance you can provide.
What you are looking for is a factory method, sometimes also called a virtual constructor (which is not technically correct, because it's neither a constructor nor a virtual method).
Instead of calling a constructor, you call a static method that calls a constructor of the class determined by the arguments passed in.
interface ITracer {
void Trace(string s);
}
class TracerA : ITracer {
public void Trace(string s) {
// ...
}
}
class TracerB : ITracer {
public void Trace(string s) {
// ...
}
}
class TracerFactory {
public static ITracer Make(string name) {
if (name.Equals("A")) return new TracerA();
if (name.Equals("B")) return new TracerB();
throw new ApplicationException("Unknown: "+name);
}
}
Much of the detail to actually make a decision is missing from your question. However, we can point you in the general directions that may answer your question.
Reflection would definitely help. Look at object.GetType() to start.
Check out different Dependency Injection or Inversion of Control (IOC) libraries. They may be just what you need.
Are you looking for something like this:
string myType = "MyNamespace." + tracerListBox.Text + ", MyAssembly";
var = Type.GetType( myType );
var property = t.GetProperty("family", BindingFlags.Static);

How to find the name of the parent class, within a base class in C#?

I inherit a class from a base class "MyLog".
If I call "Write" within the inherited class, I want it to prefix any messages with the name of the inherited class.
As this application needs to be fast, I need some way of avoiding reflection during normal program operation (reflection during startup is fine).
Here is some code to illustrate the point:
class MyClassA : MyLog
{
w("MyMessage"); // Prints "MyClassA: MyMessage"
}
class MyClassB : MyLog
{
w("MyMessage"); // Prints "MyClassB: MyMessage"
}
class MyLog
{
string nameOfInheritedClass;
MyLog()
{
nameOfInheritedClass = ?????????????
}
w(string message)
{
Console.Write(nameOfInheritedClass, message);
}
}
I suspect you want:
nameOfInheritedClass = GetType().Name;
GetType() always returns the actual type of the object it's called on.
try to explore
this.GetType()
properties in the myLog constructor, there you should be able to find type names and other properties of the correct class hierarchy.
I believe you can use GetType() to achive this.
var parentType = this.GetType().BaseType; //Will return MyLog
Where as Jon Skeet pointed out calling Name will return the actual type of the object its called on.

c# syntax help What 's coming after the constructor?

public Butler(IWeapon weapon): this(weapon, new Communicate())
{}
What does this(weapon, new Communicate()) mean?
It calls another constructor on the same type, passing in the weapon that was passed to this constructor, and a new Communicate object. I assume there is also something like:
// might actually be private
public Butler(IWeapon weapon, Communicate communicate) {...}
This approach is useful by allowing you to have multiple constructors, but only put the code in the most complex one. All the other constructors just pass the arguments (or defaults, as necessary) to the chosen constructor.
The chained constructor gets invoked before the body of the constructor that has the : this(...)
It calls a constructor in the same class but with different parameters, for example:
public class Test
{
public Test() : this("Richard")
{
}
public Test(string name)
{
}
}
It means Butler extends an instance of the current class where the weapon object passed as the argument, and a new instance of the Communicate object are passed to the class constructor.
it is calling another constructor with the signature Butler(IWeapon, ICommunicate).

Categories