Here is the class:
class Foo
{
private void Boo()
{
// Body...
}
// Other members...
}
What I need is:
Create a Foo2 class at runtime which has a copy of all Foo class members.
In Foo2 class replace Boo method by Boo2 method that has its content alternated to some extent.
Create an instance of Foo2 and invoke Boo2.
Thank you for help.
You can do it at runtime using a .NET AOP Framework event if it is not the the main purpose of this kind of framework.
I actively work on a new one which can handle it event if your method is not virtual.
You can take a look on NConcern .NET runtime AOP Framework
The monkey patch "aspect" :
public class MonkeyPatch : IAspect
{
static public void Patch(MethodInfo oldMethod, MethodInfo newMethod)
{
//update monkey patch dictionary
MonkeyPatch.m_Dictionary[oldMethod] = newMethod;
//release previous monkey patch for target method.
Aspect.Release<MonkeyPatch>(oldMethod);
//weave monkey patch for target method.
Aspect.Weave<MonkeyPatch>(oldMethod);
}
static private Dictionary<MethodInfo, MethodInfo> m_Dictionary = new Dictionary<MethodInfo, MethodInfo>();
public IEnumerable<IAdvice> Advise(MethodInfo method)
{
if (MonkeyPatch.m_Dictionary.ContainsKey(_Method))
{
yield return Advice(MonkeyPatch.m_Dictionary[_Method]);
}
}
}
Patch :
static public void main(string[] args)
{
//create Boo2, a dynamic method with Boo signature.
var boo2 = new DynamicMethod("Boo2", typeof(void), new Type[] { typeof(Foo) }, typeof(Foo), true);
var body = boo2.GetILGenerator();
//Fill your ILGenerator...
body.Emit(OpCodes.Ret);
//Apply the patch
MonkeyPatch.Patch(typeof(Foo).GetMethod("Boo"), boo2);
}
in the second hand, if you just need to call something after the original call, you are in AOP aim and you can do it like that...
Observation Aspect :
public class Observation : IAspect
{
static public void Observe(MethodInfo method, Action action)
{
//update observation dictionary
Observation.m_Dictionary[method] = action;
//release observation aspect for target method
Aspect.Release<Observation>(method);
//weave observation aspect for target method.
Aspect.Weave<Observation>(method);
}
static private Dictionary<MethodInfo, Action> m_Dictionary = new Dictionary<MethodInfo, Action>;
public IEnumerable<IAdvice> Advice(MethodInfo method)
{
if (Observation.m_Dictionary.ContainsKey(method))
{
yield return Advice.Basic.After(Observation.m_Dictionary[method]);
}
}
}
Use case :
static public void main(string[] args)
{
Observation.Observe(typeof(Foo).GetMethod("Boo"), () => { /* paste here your notification code... */ });
}
Related
This is my sample code.
public class Sample
{
public void Main()
{
Execute01<DB_MS_A>();
Execute02<DB_MS_A>();
Execute01<DB_MS_B>();
Execute02<DB_MS_B>();
Execute01<DB_MS_C>();
Execute02<DB_MS_C>();
}
public void Execute01<DbModel>()
where DbModel : IDatabaseModel
{
// do something...
}
public void Execute02<DbModel>()
where DbModel : IDatabaseModel
{
// do something...
}
}
Not to waste code lines, I want to modify Main method code like below.
public void Main()
{
var dbList = new List<dynamic>() {
DB_MS_A,
DB_MS_B,
DB_MS_C
};
dbList.ForEach(db => {
Execute01<db>();
Execute02<db>();
});
}
But it seems impossible to add static value to List.
Also Delivering static value as lambda arguments is not possible.
Is there any way for method Refactoring?
I think you can simply use a list of type:
var listInputType = new []{
typeof(string),
typeof(int),
};
But I don't think you can pass run time type to generique as they need compile type.
But we can use reflexion like in this SO question: C# use System.Type as Generic parameter.
public class Program
{
public static void Main()
{
var listInputType = new []{
typeof(string),
typeof(int),
};
foreach(var myType in listInputType){
typeof(Program).GetMethod("M1").MakeGenericMethod(myType).Invoke(null, null);
typeof(Program).GetMethod("M2").MakeGenericMethod(myType).Invoke(null, null);
}
}
public static void M1<t>()
{
Console.WriteLine($"M1<{typeof(t).Name}>()");
}
public static void M2<t>()
{
Console.WriteLine($"M2<{typeof(t).Name}>()");
}
}
C# online demo
I have multiple classes that inherit from IPrint. I want to instantiate these classes using a factory but I want to maintain a single instance of each type.
Is this possible?
Please find my sample code below.
public interface IPrint
{
void DoPrint();
}
public class DigitalPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class InkPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class PrintFactory
{
private static IDictionary<IPrint, object> prints = new
Dictionary<IPrint, object>();
private PrintFactory()
{
}
public static IPrint GetPrint(PrintType type)
{
// return instance depending on type. Instantiate only once
//like singleton
// How to write so that it returns a single instance depending
//on type
return null;
}
}
public enum PrintType
{
DigitalPrint,
InkPrint
}
Can someone give me some idea if this is possible?
Thanks.
You can create IPrint instances when initializing Dictionary<PrintType, IPrint>:
private static IDictionary<PrintType, IPrint> prints =
new Dictionary<PrintType, IPrint> {
{ PrintType.DigitalPrint, new DigitalPrint() },
{ PrintType.InkPrint, new InkPrint() }
};
Getting print (thus print is a class, the same instance will be returned for each request):
public static IPrint GetPrint(PrintType type)
{
IPrint print;
if (!prints.TryGetValue(type, out print))
return null;
return print;
}
If you don't want to create IPrint instances until the client asks for them, you can use Dictionary<PrintType, Lazy<IPrint>>:
private static IDictionary<string, Lazy<IPrint>> prints =
new Dictionary<string, Lazy<IPrint>> {
{ PrintType.DigitalPrint, new Lazy<IPrint>(() => new DigitalPrint()) },
{ PrintType.InkPrint, new Lazy<IPrint>(() => new InkPrint()) }
};
Getting print (in this case only one instance of each IPrint type will be created, but not before someone tries to get the instance of that type):
public static IPrint GetPrint(PrintType type)
{
Lazy<IPrint> factory;
if (!prints.TryGetValue(type, out factory))
return null;
return factory.Value;
}
Though I would consider using dependency injection framework instead of implementing such functionality manually.
Further reading: Ninject or Autofac
Yes, it's possible.
This creates the IPrint's before they're needed. You could make them lazily created, instead.
public class Program
{
public static void Main(string[] args)
{
var factory = new PrintFactory();
Console.WriteLine(PrintFactory.GetPrint(PrintType.DigitalPrint));
Console.WriteLine(PrintFactory.GetPrint(PrintType.InkPrint));
}
}
public interface IPrint
{
void DoPrint();
}
public class DigitalPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class InkPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class PrintFactory
{
// Make the dictionary from PrintType to IPrint instead of IPrint to object
private static IDictionary<PrintType, IPrint> prints = new Dictionary<PrintType, IPrint>();
// Initialize prints in a static constructor.
static PrintFactory()
{
prints.Add(PrintType.DigitalPrint, new DigitalPrint());
prints.Add(PrintType.InkPrint, new InkPrint());
}
public static IPrint GetPrint(PrintType type)
{
if (!prints.ContainsKey(type))
{
// TODO: Maybe throw an exception or log?
}
return prints[type];
}
}
public enum PrintType
{
DigitalPrint,
InkPrint
}
I would get rid of the enum and make a generic method:
public static IPrint GetPrint<T>() where T : IPrint, new ()
{
foreach (var key in prints.Keys) {
if (key is T)
return null;
}
return new T();
}
I'm trying to create a "wrapper" around a dynamic object so I can keep method names on dynamic object matching the names of the methods in the wrapping class.
What I need to do is provide the helper a dynamic object, and the name of the method i want to call on it (via [CallerMemberName]), and the args for the call. I can't figure out how to invoke the call on the dynamic object. How can I do this?
class Program
{
static void Main(string[] args)
{
var dyn = new ClassWithDynamicProperty();
dyn.SendMessage("test");
Console.ReadKey();
}
}
public class ExampleDynamicClass
{
public void SendMessage(string msg)
{
Console.WriteLine(msg);
}
}
public class ClassWithDynamicProperty
{
public ClassWithDynamicProperty()
{
MyDynObject = new ExampleDynamicClass();
}
public dynamic MyDynObject { get; set; }
public void SendMessage(string theMessage)
{
//i want to replace this:
MyDynObject.SendMessage(theMessage);
//with this:
DynamicHelper.CallDynamic(MyDynObject, new object[] { theMessage });
}
}
public static class DynamicHelper
{
public static void CallDynamic(dynamic source, object[] args, [CallerMemberName]string methodName = null)
{
//source.methodName(args); How can i invoke this?
}
}
Turns out it's not that hard after all. I didn't know if normal reflection would work with dynamic types. All resources I found for dynamic objects involved overriding TryInvokeMember, which wasn't an option. Here's missing code:
var method = ((object)dynamicObject).GetType().GetMethod(methodName);
method.Invoke(dynamicObject, args);
I need to combine multiple interfaces a runtime to create a new type. For example I might have the following interfaces:
public interface IA{
}
public interface IB{
}
At runtime I want to be able to generate another interface so that in the following sudo code works:
Type newInterface = generator.Combine(typeof(IA), typeof(IB));
var instance = generator.CreateInstance(newInterface);
Assert.IsTrue(instance is IA);
Assert.IsTrue(instance is IB);
Is there a way to do this in .Net C#?
It is possible because of power of Castle Dynamic Proxy
public interface A
{
void DoA();
}
public interface B
{
void DoB();
}
public class IInterceptorX : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(invocation.Method.Name + " is beign invoked");
}
}
class Program
{
static void Main(string[] args)
{
var generator = new ProxyGenerator();
dynamic newObject = generator.CreateInterfaceProxyWithoutTarget(typeof(A), new Type[] { typeof(B) }, new IInterceptorX());
Console.WriteLine(newObject is A); // True
Console.WriteLine(newObject is B); // True
newObject.DoA(); // DoA is being invoked
}
}
Is it possible to do something like the following:
public class ChildClass : BaseClass
{
public ChildClass(BaseClass o)
{
base = o;
}
}
Basically, I want a transparent way to wrap a base class inside of other functionality. One example I've thought of is a custom Settings Provider which transparently audits the settings passed through it.
public class SettingsAuditor : SettingsProvider
{
public SettingsAuditor(SettingsProvider o)
{
base = o;
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
base.SetPropertyValues(context, propvals);
}
}
Then I could do the following:
mySettingsProvider = new SettingsAuditor(mySettingsProvider);
And all changes would go through the overridden SetPropertyValues before passing to the original object.
I could use a private SettingsProvider member, but then I either cannot inherit from SettingsProvider, or have an entire SettingsProvider (base) not being used at all.
I'm using C# 4.0 and .Net 4.0.
You cannot do base = o;
What you're looking for is the Decorator Pattern), which is a way to compositionally add functionality at runtime (vs. inheritance).
Instead of trying to set the base, you just contain the inner member. As long as the wrapper implements the same interface or base class as the inner object, you can pass back the new wrapper. You can wrap as many decorators as you want.
Consider:
public interface ICar
{
void Drive();
}
public class Car : ICar
{
public void Drive()
{
Console.WriteLine("vroom");
}
}
public class BuckleUp : ICar
{
ICar car;
public BuckleUp(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("click!");
car.Drive();
}
}
public class CheckMirrors : ICar
{
ICar car;
public CheckMirrors(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("mirrors adjusted");
car.Drive();
}
}
Now consider you have a method that accepts an ICar and tells it to drive. You could give it a Car, and it would work, but you could also wrap that car in a BuckleUp and a CheckMirrors and you wouldn't have to change that method at all. You've modified functionality through composition using the Decorator Pattern.
No. This looks like it should be a Composition vs Inheritance issue. You need to evaluate whether you are a "is a" or a "has a."
A little help for your journey
This is not a complete implmentation and it could probably be done much cleaner with expression trees... but this was a quick swing at faking AOP using DynamicObject with .Net 4.0.
public class MyDynamicWrapper<T> : DynamicObject
{
public T Wrapped { get; private set; }
public Action<T> Pre { get; private set; }
public Action<T> Post { get; private set; }
public MyDynamicWrapper(T wrapped, Action<T> pre, Action<T> post)
{
this.Wrapped = wrapped;
this.Pre = pre;
this.Post = post;
}
public override bool TryGetMember(
GetMemberBinder binder,
out object result)
{
var type = typeof(T);
var method = type.GetMethod(binder.Name);
if (method != null)
{
Func<object> func = () =>
{
if (Pre != null)
Pre(Wrapped);
// support for input parameters could be added here
var ret = method.Invoke(Wrapped, null);
if (Post != null)
Post(Wrapped);
return ret;
};
result = func;
return true;
}
return base.TryGetMember(binder, out result);
}
}
public class MyDynamicWrapper
{
public static MyDynamicWrapper<T> Create<T>(
T toWrap,
Action<T> pre = null,
Action<T> post = null)
{
return new MyDynamicWrapper<T>(toWrap, pre, post);
}
}
public class MyObject
{
public void MyMethod()
{
Console.WriteLine("Do Something");
}
}
class Program
{
static void Main()
{
var myobject = new MyObject();
dynamic mydyn = MyDynamicWrapper.Create(
myobject,
p => Console.WriteLine("before"),
p => Console.WriteLine("after"));
// Note that you have no intellisence...
// but you could use the old implmentation before you
// changed to this wrapped version.
mydyn.MyMethod();
/* output below
before
Do Something
after
*/
}
}
No, but you could fake it:
public class SettingsAuditor
{
SettingsProvider #base;
public SettingsAuditor(SettingsProvider o)
{
#base = o;
}
public void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
#base.SetPropertyValues(context, propvals);
}
}
Note here, #base isn't the actual base, just a varaible named base