I've noticed in the tutorials for interception that you can target a method and intercept it. I.e.
Kernel.Bind<Foo>().ToSelf();
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(), invocation => {} );
The documentation/tutorial does not cover what to do in the instance that the method you're trying to intercept has parameters i.e if ThrowsAnError accepted a string as a parameter.
Kernel.Bind<Foo>().ToSelf();
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(**param goes here**), invocation => {} );
At the time of binding I do not have access to the params so I was wondering whether I am going about this the wrong way?
Edit
Working example
I think you are misunderstanding what happens. Your Foo object is replaced with an decorator that contains the interceptor. Here is a simplistic example:
public class FooDecorator : Foo
{
private readonly Foo decorated;
public FooDecorator(Foo foo) { this.decorated = foo; }
public void ThrowsAnError(object param1, int param2)
{
// calls the decorated instance with supplied parameters
this.decorated.ThrowsAnError(param1, param2);
}
}
In other words, the parameters that are supplied when the resolved Foo is called, will be passed on to the decorated instance.
With interception however, this is all a bit more indirect (and slower), but the concept is the same. I must admit that I'm not familiar with Ninject interception, but there is probably a Proceed method on the invocation object. In other words, you should do something like this:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(),
invocation =>
{
try
{
// calls the decorated instance with supplied parameters
invocation.Proceed();
}
catch (Exception ex)
{
Kernel.Get<ILogger>().Log(ex);
}
} );
UPDATE
I assume that the first argument of the InterceptReplace<T> method is not an delegate, but an expression tree, such as Expression<Action<T>>. This method is in fact not called, but it is analyzed to find out which method to intercept. In other words, since the method is never called, you can just supply any argument you which. The trick is to let the C# compiler know which method overload (if any) to use. It doesn't matter if you supply rubbish. When both arguments are reference types, this will probably work:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),
Related
I have the following class:
public class MyClass : IMyClass
{
public string MyFunc(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new Exception("Blank Name");
}
return name;
}
public double MyFuncWrapper(string name)
{
var value = MyFunc(name);
return value;
}
In trying to test it, I was under the impression that NSubstitute's ForPartsOf effectively subclassed my class and replaced the flagged methods; so I did this:
[Fact]
public void TestMyFuncWrapper()
{
// Arrange
var myClass = Substitute.ForPartsOf<MyClass>();
myClass.MyFunc(Arg.Any<string>()).Returns("Test");
// Act
var result = myClass.MyFuncWrapper("");
// Assert
Assert.Equal("Test", result);
}
However, I get the exception raised from, what I understood to be, my substituted method. Oddly, it appears that the following line:
myClass.MyFunc(Arg.Any<string>()).Returns("Test");
Is actually calling the concrete function immediately. Looking here, it appeared that a construct like this may solve the problem (although it does use the phrase "playing it safe" which sounds quite vague):
myClass.When(a => a.MyFunc(Arg.Any<string>())).DoNotCallBase();
However, calling this actually invokes MyFunc immediately in the same way. Clearly I'd misunderstood the ForPartsOf method; my question is: can I do what I'm attempting using NSubstitute, or do I need to resort to manually subclassing MyClass?
This is by design for NSubstitute (and for most mocking frameworks).
The docs state:
For starters, NSubstitute can only work with virtual members of the
class, so any non-virtual code in the class will actually execute!
Thus, you need to add virtual to the function declarations you plan to mock.
Or (as per the docs):
If possible, stick to substituting interfaces.
I have a C# code
private class EvaluationTask : Task<Solution> {
private Problem problem_;
private Solution solution_;
public EvaluationTask(Problem problem, Solution solution)
{
problem_ = problem;
solution_ = solution;
}
}
Now, I am getting error System.Threading.Tasks.Task<> does not contain constructor that takes 0 arguments. From previous answers posted, I found that one has to define empty constructor in the base class. But since my base class is Task<>, how do I add an empty constructor to it?
Any help would be highly appreciated!
Edit: I have to inherit task<> because I have to use the method EvaluationTask in a code:
taskList_ = new List<Task<Solution>>();
taskList_.Add(new MultithreadedEvaluator.EvaluationTask (problem_, solution));
I don't know about task composition, so if it is necessary can anyone help with that? Or if by any way I can avoid inheriting Task and still implement taskList_.Add()?
When you inherit from a class, in your constructors you need to call any of the constructors of the base class. In your case, since you aren't calling any constructor, the compiler try to call a parameterless constructor of the base class, but Task<> haven't a parameterless constructor.
As you can read here, inheriting from Task<> probably isn't a good idea, but you can do something like this:
class EvaluationTask : Task<Evaluation>
{
public EvaluationTask()
: base(DoWork) { }
private static Evaluation DoWork()
{
//...
}
}
When using Task<T>, you must supply the Func<> or Action<> delegate (i.e., function pointer to the desired work to perform) as a constructor argument. It is indeed somewhat unfortunate that there isn't any constructor which lets you bypass this requirement and supply the delegate at a later time (yet obviously still prior to calling Start()), since this severely hampers the ability to extend the Task and Task<TResult> classes via inheritance altogether.
The reason it's a crippling omission is that no delegate you supply as a constructor argument can possibly directly incorporate a reference to the instance you are trying to construct, since that instance (again, obviously) doesn't exist yet, chicken/egg style.
Hence #Arturo's answer, which shows that you can, in fact, supply a static delegate, but since such a delegate has no obvious way of referencing one particular Task instance, it essentially defeats the purpose of inheriting from Task in the first place.
--- reflection disclaimer ---I've been using this technique in my own projects for years on .NET Framework 4.7 (desktop) with no problems whatsoever, but please note that code which uses reflection to access non-public behavior is subject to breakage if the .NET internals change in a later version. You have been warned.
Here's a more flexible workaround for the problem, a general-purpose abstract base class for Task<TResult> which allows you to provide the desired work code in the normal way for derived type hierarchies: as an instance method override. This is a reflection solution; the way it works is to provide a dummy "placeholder" delegate to the base constructor call, but then immediately in the constructor body, swap it out for the "real," desired abstract instance work method, which at that point is no longer unknowable or rather unbindable.
abstract class TaskBase<TResult> : Task<TResult>
{
readonly static FieldInfo m_action =
typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
readonly static Func<TResult> _dummy = () => default;
public TaskBase(CancellationToken ct, TaskCreationOptions opts)
: base(_dummy, ct, opts) =>
m_action.SetValue(this, (Func<TResult>)function);
public TaskBase(CancellationToken ct)
: this(ct, TaskCreationOptions.None)
{ }
public TaskBase(TaskCreationOptions opts)
: this(default, opts)
{ }
public TaskBase()
: this(default, TaskCreationOptions.None)
{ }
protected abstract TResult function(); // <-- override with your work code
};
To use this, simply inherit from TaskBase<TResult>, and override the abstract method function() to implement your task work logic. There is no need for a version of this base class where the work function accepts a AsyncState argument/parameter(s), since you can simply declare all the relevant context for the specific work instance as additional instance fields (and instance methods, and instance properties...) in your derived class. So the constructor variations I declared exactly match those provided by Task<TResult>, but minus the 'function' and 'state' arguments. And finally, don't forget to call Start() when your packaged work instance is ready to go!
The above is a actually a simplified version of the TaskBase<TResult> code I've had much success with. My enhanced version avoids creating the Func<TResult> delegate which must be created for each TaskBase instance in order to "wrap" the C# method function() as an instance delegate. Instead of initially providing a 'dummy' delegate to the base constructor, I always provide (the same) static delegate, a singleton which acts as a "thunk" that universally reinterprets, or "upcasts" a Task<TResult>'s AsyncState object as a pertinent TaskBase<TResult> instance, and then calls function() directly on that instance. Like so:
static Func<Object,TResult> thunk = obj => ((TaskBase<TResult>)obj).function();
So fn_redirect is the only "excess" delegate we need to create once at startup, and this singleton is always passed-in as the base constructor work delegate. Now as with that constructor argument, the "async state" object is also only passed in as a constructor argument and normally cannot later be changed. We don't need a "dummy" in this approach, because you can--and should--pass in 'null' for state. Similar to before we use reflection to set a field, but this time it's m_stateObject field instead of m_action, to replace the 'null' value we just installed for the instance this pointer:
public TaskBase(CancellationToken ct, TaskCreationOptions opts)
: base(thunk, default(Object), ct, opts)
{
m_stateObject.SetValue(this, this);
}
Voila, allocating one extra delegate for each TaskBase instance is avoided. Finally, recall that there are no adverse loss of capability when co-opting the state object for the purpose of this enhancement because as I mentioned earlier, the whole AsyncObject argument-passing mechanism is unnecessary when you entirely control the derived class you are writing.
Here is an inheritable class that inherits from Task<T>, and allows delayed assignment of the task's function. The constructor takes no arguments. The function is assigned by the property Function.
public class FlexibleTask<T> : Task<T>
{
private readonly Helper _helper;
public Func<T> Function { set { _helper.SetFunction(value); } }
public FlexibleTask() : base(GetFunction())
{
this._helper = TempHelper;
TempHelper = null;
}
private static Func<T> GetFunction()
{
Func<T> function = Default;
var helper = new Helper();
helper.SetFunction = f => function = f;
TempHelper = helper;
return () => function();
}
private static readonly Func<T> Default = () =>
throw new InvalidOperationException("Function is not set.");
[ThreadStatic] private static Helper TempHelper;
private class Helper
{
public Action<Func<T>> SetFunction {get; set;}
}
}
Usage Example:
public class EvaluationTask : FlexibleTask<int>
{
}
var task = new EvaluationTask();
task.Function = () => 13;
task.Start();
var result = await task;
Console.WriteLine($"Result: {result}");
Output:
Result: 13
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.
public class StoreController : Controller
{
public string Index()
{
// implicitly specified instance does not work
//return GetMemberName();
// must specify this explicitly
return this.GetMemberName();
}
}
public static class Utilities
{
public static string GetMemberName(this Controller caller,
[CallerMemberName] string memberName = "")
{
return caller.GetType().FullName + "." + memberName;
}
}
Why do we have to explicitly specify this when invoking an extension method from within a method of a class being extended?
In my mental model, we usually can omit this such as when we initialize fields, for example.
An extension method is technically not a method attached to your class.
yourClass.ExtensionMethod() isn't the same as yourClass.ClassMethod().
Basically, what you are doing is getting a convenient way of doing this:
ExtensionMethod(YourClass yourClass) {
//do something
return yourClass;
}
That is my understanding of an extension method. It's a convenient way of calling a method against a class you can't change. So, that's why you can't just call it without this. It's not a class method.
Extension method is just a syntactic sugar to call a static method. Tthis line of code return this.GetMemberName(); is actually convert to a call to static method like Utilities.GetMemberName(this);
As you can see, you have to send this to the static method and that is the reason why you need this keyword.
Without being present at the design board meeting where this was decided it's hard to say why it's like that.
In this text I use method or instance method in the sense of a function associated with a specific object instance and I use function in a mathematical sense. A function receives a number of arguments and creates a result (which is potentially void)
If we do not consider virtual methods which are more complex because the actual function to be called is determined runtime then any and all method calls are syntactic sugar. If we have two methods defined below
internal static class Extensions {
public static string FooEx(this MyClass self){
return self.ToString();
}
}
internal class MyClass {
public string Bar(){
var s1 = Foo();
var s2 = this.FooEx();
}
private string Foo(){
return ToString();
}
}
Then both will be translated to a function call where the first (and only) argument in both cases will be the object identified by this. If you are doubtful about this then look at the IL produced for any call to an instance method and you will notice there's an extra argument compared to the declaration in code. This argument is the thisreference, which is always passed as the first argument to an instance method.
So in the case of an instance method the compiler still need to determine which object to pass as the first argument to the function. That is exactly the same it has to do if you are calling an extension method without this which also means that can't be the real reason why you have to use this in front of an extension method.
In the compiler for Marvin, a compiler build on top of the Mono compiler I had to do a similar trick as C# does with extension methods and wondered why the specs require the this
The real reason why the compiler enforces you to use this before an extension method is that the specs says so. What the reason behind that decision is would need the attention of some one like #EricLippert who where probably there when they decided on that requirement
I am implementing a web control that gets an object (as an argument) with a certain function -- lets call it DoStuff() -- the object can belong to different classes, which are all derived from an abstract class -- lets call it SuperClass -- this SuperClass does not have the DoStuff() method.
So my question is: Is there a way in C# to call a method of an Object on runtime if this method exists in the object without having to cast it to the derived classes.
Something like (I know this does not work but I think it expresses better what I would like to accomplish):
if(myObject.Functions["DoStuff"] != null){
myObject.executeFunction("DoStuff");
}
Is this at all possible??
It's possible with reflection, like:
uses System.Reflection
....
public void ExecuteMethod(object thing, string method)
{
Type type = thing.GetType(); //gets the runtime type of the object
MethodInfo mi = type.GetMethod(method); // null if method not found
mi.Invoke(thing, null); //invokes the method on the "thing" object,
//passing null arguments, and returns the result
}
However, in your scenario it would be better (if possible) to create an interface IDoStuff that will have DoStuff method, and make all classes that will be possibly called to do stuff implement it.
That way your code will be simpler and less prone to errors, like this:
public void ExecuteDoStuff(object thingy)
{
if (thingy is IDoStuff)
((IDoStuff)thingy).DoStuff();
else
throw new Exception("thingy cannot do stuff");
}
Well, in C# 4 you could write:
dynamic d = myObject;
d.DoStuff();
That will throw an exception if the DoStuff() method can't be bound, but the binding is only checked at execution time.
It's relatively tricky to find out whether or not that's going to work without just doing it - you could always catch the exception of course, but it's not ideal.
You could try to find it with reflection, but again I don't see that as an idea approach.
The bigger question is why the abstract class doesn't have the DoStuff method, at least as an abstract method. That would be a far better solution.
If only some of the subclasses have the DoStuff method, it would be better to put that into an interface:
public interface IStuffable
{
void DoStuff();
}
Then make the appropriate subclasses implement IStuffable, and you can write:
IStuffable stuffable = myObject as IStuffable;
if (stuffable != null)
{
stuffable.DoStuff();
}
There are a few ways to do so. I start with the recommended ones:
Create an interface wich contains you DoStuff() method an implement it in all your classes. Then cast your object to that interface:
interface IDoStuff {
void DoStuff();
}
// call it on your object
((IDoStuff)object).DoStuff();
Extend your baseclass to contain your DoStuff() Method (if possible)
Use reflection to call the method:
object.GetType().GetMethod("DoStuff").Invoke();