Reputation: 1070
i am trying to achieve something like this
Player lebron = new Player("LeBron", 23, 2.03f);
lebron.Rings = 3;
lebron.Team = "Cleveland";
Player p = Proxy.For<Player>().Override("ToString", (target, argz) =>
{
return target.name;
}).Proxify(lebron);
where any method given by the first parameter of Override can be replaced by a Func<T, object[], object // where T is the same type use in For, in this case Player
// and target is the T object (Player lebron in this case) and argz is the array of possible parameters
The way i figured out to do this is to have a Dictionary with the method name as Key and storing the corresponding Func<T, object[], object
.
With Proxify i am returning a new Type that was created dynamically, extending the base type T
and copying every property or fields from the original object to this newly dynamically created one. This is working for now.
Problem: How to i Override any function specified with the name given in Override
, and its execution should be the Func<T, object[], object>
handler given ?
I have tried
foreach(MethodInfo mi in cloneType.GetMethods(FLAGS))
{
if (overr.ContainsKey(mi.Name)){
Ops op;
if(! overr.TryGetValue(mi.Name, out op)) continue;
//tb.DefineMethodOverride(op.MethodInfo, mi);
MethodBuilder mb = tb.DefineMethod(mi.Name,
MethodAttributes.Public
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.Virtual
| MethodAttributes.Final,
CallingConventions.HasThis,
mi.ReturnType, op.GenericTypes);
ILGenerator il = mb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
}
}
Ops op is just a wrapper for the Func, it stores 2 properyies, the MethodInfo of the Func, and a Type[] for it GenericTypes, i can also access the Func itself if needed.
I think that for each method in the dictionary i must create a new method in my dynamically created type, where this new methods body is only the execution of the associated Func, but i can't seem to make this work.
Some help would be appreciated, and if you think i'm in the wrong direction please advise me.
Note: I can't use other Frameworks or Libraries as this is a Friends assigment and i found this problem intriguing to implement and i am trying to help him.
Proxy is a class that i created with only the For method which returns an object where you can call Override (this method returns this
) and then when Proxify is called it returns something that extends T
with all values copied but some methods overriden like the code tells.
Upvotes: 3
Views: 3176
Reputation: 112782
If all the public members of Player
are virtual, you could simply derive a wrapper class and use it as a base class for proxies
Let's assume that Player
has a ToString
and a Run
method. Then delcare
public abstract class PlayerProxyBase : Player
{
protected readonly Player _player;
public PlayerProxyBase(Player player)
{
_player = player;
}
public override void Run()
{
_player.Run();
}
public override string ToString()
{
return _player.ToString();
}
}
Now you can create a concrete Proxy class like this
public class MyPlayerProxy : PlayerProxyBase
{
public MyPlayerProxy(Player player)
: base(player)
{ }
public override string ToString()
{
return _player.Name;
}
}
Create a proxy dynamically:
Player p = new MyPlayerProxy(lebron);
Upvotes: 1