I´m working with C# + Unity (2.1). Intercepting methods works fine if a call comes from outside, but between methods inside the same class only the first method is intercepted.
For example:
[InterceptorAttribute]
public int A(int a, int b)
{
return B(a, b);
}
[InterceptorAttribute]
public int B(int a, int b)
{
return a+b;
}
The call to method B() is not intercepted.
Can anyone help?
If you look at how interception is implemented, it becomes clear as to why this happens. An interceptor is basically a proxy that wraps around the original object and forwards calls to it, in addition to calling any associated handlers:
public int A(int a, int b)
{
callHandlers();
return originalObject.A(a, b);
}
public int B(int a, int b)
{
callHandlers();
return originalObject.B(a, b);
}
Even though the two calls are individually intercepted, once originalMethod.A is invoked, the call to B will only invoke originalObject.B, not proxy.B.
Perhaps if you explain what you're using interception for, there may be a better solution to what you're trying to do.
Related
I have groups of logic that consist of static classes such as:
static class A {
static int mutate(int i) { /**implementation*/ };
static double prop(double a, double b) { /**implementation*/ };
}
static class B {
static int mutate(int i) { /**implementation*/ };
static double prop(double a, double b) { /**implementation*/ };
}
In this case, A and B are static classes that implement the same behavior via a group of functions (e.g. mutate). I would like to use something like an interface for this pattern, however since static classes cannot implement interfaces I am not sure what to do. What is the best way to implement this type of behavior cleanly?
EDIT:
Here is an example of what I am currently doing. The classes have no state so normally I would make them static.
Interface IMutator {
int mutate(int i);
}
class A : IMutator {
int mutate(int i) { /**implementation*/ };
}
class B : IMutator {
int mutate(int i) { /**implementation*/ };
}
class C {
public List<IMutator> Mutators;
public C(List<IMutator> mutators) {
Mutators = mutators;
}
}
//Somewhere else...
//The new keyword for A and B is what really bothers me in this case.
var Cinstance = new C(new List<IMutator>() {new A(), new B() /**...*/});
The stateless class doesn't have to be static.
Moreover, static dependencies isn't a good choice, when you want to write unit tests, or when you want to extract some common interface (as in your case).
It's OK to have non-static classes, containing logic only. E.g., people build ASP .NET applications using stateless controllers.
So, just throw away static and extract an interface.
Apart from #Dennis answer (which I have +1'ed, and it's indeed the way to go), other approach that may work, is having a set of functions (Func<>) and/or actions (Action<>) and resolve them using reflection. The code would not be specially elegant nor performant, but it works.
I've made a quick example on dotnetfiddle
Note that this might be a duplicate of this question, I'm not entirely sure.
My problem is that I have a class library project which has a reference to a third-party type library (COM). I want to put contracts into the methods in the class library, like so:
public class foo
{
public static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
And then have a client project make use of this method, e.g.
var n = foo.divide(null, 4, 2);
But I'd also like the client project also use contracts in some of its methods. So, I set the Code Contracts properties on both projects to 'Perform Runtime Contract Checking' (without which you get the runtime assert telling you that it needs this setting).
Now, when I then try to compile the client, I get the following error:
Could not resolve member reference: my_class_lib.foo::divide.
ccrewrite : error : Rewrite aborted due to metadata errors.
Which seems unavoidable - any time a method is called which has a type from the third party type library this happens. Remove the type from the method's signature and it's fine.
Can anyone explain why this happens? Is this a clue that the structure of my code is fundamentally flawed (if so, why?), or is it a quirk of code contracts? Is there a recommended fix for this problem?
To be honest I don't know why ccrewrite has a problem with interop types but I can give you 3 workarounds:
Solution 1
This one is the simplest:
Go to list of references for a project.
Find third-party type library.
Right click.
From the context menu select Properties.
Change Embed Interop Types from True to False.
You have to do that for both projects. The drawback of this solution is that after a build you will get an additional interop assembly in the bin folder.
Solution 2
Another solution might be to remove types from a third-party type library from a public interface i.e.:
public class foo
{
public static int divide(int a, int b)
{
return divide(null, a, b);
}
private static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
Of course you can do that only if you do not need to use TypeFromTypeLib in your client.
Solution 3
If you need to use TypeFromTypeLib in your client you may write a wrapper for this class i.e.:
public class MyTypeFromTypeLib
{
//...
}
public class foo
{
public static int divide(MyTypeFromTypeLib mytftl, int a, int b)
{
var tftl = new TypeFromTypeLib();
//Map MyTypeFromTypeLib to TypeFromTypeLib
//...
return divide(tftl , a, b);
}
private static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
However, this solution is cumbersome because additional classes are needed.
I have a public method in a class that internally calls a particular private method within that class. It looks something like this :
public class MyClass : IMyClassInterface
{
public List<int> MyMethod(int a, int b)
{
MyPrivateMethod(a, b, ref varList, ref someVal);
}
private void MyPrivateMethod(int a, int b, ref List<int> varList, ref double someval)
{
}
}
Now, I basically want to test this public method using NUnit. I am using NMock 2.0 for mocking. How do I do it? Since, it internally calls this private method which I do not want to make public. Or is there a way to do it if I turn the private method to protected instead?
Now, I basically want to test this public method (...)
This is great. This is what you should be doing. Forget about internal details for a moment. From public method point of view, is there any difference between these two snippets?
// Your current implementation
public void MyMethod(int a, int b)
{
MyPrivateMethod(a, b);
}
private void MyPrivateMethod(int a, int b)
{
var c = a + b;
// some more code
}
// Private method inlined
public void MyMethod(int a, int b)
{
var c = a + b;
// some more code
}
Whoever calls (public) MyMethod will not be able to notice any difference between these two. End result is the same. It doesn't matter there is a private method call, because as far a public API is concerned it is irrelevant. You could inline said private method, make it gone forever, and from public consumer point of view nothing changes. End result is the only thing that's important. You test end result observable by code consumer. Not some internal gibberish.
Important realization is this:
Properly designed SOLID code will never put you in a position which will require you to do private mocking. Source of the problem? Bad design.
Source: How to mock private method - solutions
Yep. Sad but true, your design is not that great. Depending on whether you want to change that or not, there are few approaches you could take:
don't try to mock private details, focus on public API (doesn't help with design issue)
extract private method to class, introduce dependency (long-term solution, improves design and makes code easily testable)
make private method protected, override in test as suggested in other answer (doesn't help with design issue, might not yield valuable test)
Whichever you chose I leave up to you. However, I'll emphasize it one more time - mocking private method is not unit testing, library or tools problem - it is a design problem and is best solvable as such.
On a side note, (if you can) don't use NMock2. It's a library with last changes from 2009. It's like having a 30 year old car which was last serviced 15 years ago. There are much better ones nowadays (FakeItEasy, Moq, NSubstitute).
Yes the "trick" is to use protected instead of private and then inherit the class and run the test on the new class that executes the protected method.
This is a very common way to make brownfield and legacy code testable.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
MyClassTestWrapped t = new MyClassTestWrapped();
Assert.IsTrue(t.MyPrivateMethod(...));
Assert.IsTrue(t.MyMethod(...));
MockFactory _factory = new MockFactory();
Mock<MyClassTestWrapped> mock;
mock = _factory.CreateMock<MyClass>();
mock.Expects.One.MethodWith(d => d.MyPrivateMethod()); // do the nmock magic here
}
}
public class MyClass : IMyClassInterface
{
public List<int> MyMethod(int a, int b)
{
MyPrivateMethod(a, b, ref varList, ref someVal);
}
// here change to protected
protected void MyPrivateMethod(int a, int b, ref List<int> varList, ref double someval)
{
}
}
public interface IMyClassInterface
{
}
public class MyClassTestWrapped : MyClass
{
public List<int> MyMethod(int a, int b)
{
base.MyMethod(a, b);
}
public List<int> MyPrivateMethod(int a, int b,ref List<int> varList, ref double someval)
{
base.MyPrivateMethod(a, b, ref varList, ref someval);
}
}
While currently you have to refactor your code to lose the private modifier ( wrappers and what not), You can do it fairly easy with tools Like Typemock Isolator.
I added some code to your example to write the test:
public class MyClass
{
public List<int> MyMethod(int a, int b)
{
List<int> varList = new List<int>();
double someVal = 0;
MyPrivateMethod(a, b, ref varList, ref someVal);
return varList;
}
private void MyPrivateMethod(int a, int b, ref List<int> varList, ref double someval)
{
}
}
With this straight forward approach you just fake the private method as it is in your code (no changes in the production), even it's ref parameters:
[Test]
public void TestMethod1()
{
//Arrange
var myClass = new MyClass();
var expectedVarList = new List<int> {1,2,3};
Isolate.NonPublic.WhenCalled(myClass, "MyPrivateMethod")
.AssignRefOut(expectedVarList, 0.0)
.IgnoreCall();
//Act
var resultVarList = myClass.MyMethod(0, 0);
//Assert
CollectionAssert.AreEqual(expectedVarList, resultVarList);
}
I have ScriptA with a lot of void functions:
void methodOne() {
some code
}
void methodTwo(int a, int b) {
}
I want to pass to static method of another script. Lets say it scriptB:
ScriptB.staticMethod(methodOne, some, other, primitive, parameters);
ScriptB.staticMethod(methodTwo(a, b), some, other, parameters);
The main Idea of my scripts is that ScriptB will get datas from server and call methods that got from ScriptA to make changes in my game depending on data.
I am not sure what you are trying to achieve here.
But to answer your question, you can pass methods as parameters using delegates. Here is an example:
public class ScriptA
{
public delegate void MethodOneDelegate(int a, int b);
public void MethodOne(int a, int b)
{
Console.WriteLine(a + b);
}
}
public static class ScriptB
{
public static void StaticMethod(ScriptA.MethodOneDelegate function, int a, int b)
{
function(a, b);
}
}
public static void Main()
{
ScriptA scriptA = new ScriptA();
ScriptB.StaticMethod(scriptA.MethodOne, 1, 2);
}
There is alternative solutions, you can take a look at System.Func and System.Action.
Do you need to start the methods when you put them as parameters? Or do you need the values from those methods?
Either way, you could do two things, either try this or just pass the name of the method as string and in your method check which name has been entered and start that method in your method.
TL;DR: Can I somehow create an algorithm that can use different functionality in the inner loop, and still get that "functionality" inlined, without resorting to copy/paste or if/else statements?
I am trying to create an algorithm that basically looks like this:
for(var i=0; i<big; i++) {
for(var j=0; j<big2; j++) {
// ... processing
var x = SomeFunc(a, b, c);
// ... more processing
}
}
I want the algorithm to be run for a number of possible functions (SomeFunc above), each called a large number of times per run. Each SomeFunc function is very simple (usually an arithmetic expression).
Now, to get acceptable performance out of this algorithm, it is imperative that SomeFunc is inlined. However I fail to get the function inlined while still allowing for multiple functions.
I realize this means that the algorithm function has to be JITted multiple times, but I was hoping that a construct like this would work:
interface ISomeFunc {
int SomeFunc(int a, int b, int c);
}
private sealed class SomeFunc1 : ISomeFunc {
public int SomeFunc(int a, int b, int c) {
return ....;
}
}
private static void RunMyGenericAlgo<T>(T func) where T : ISomeFunc
{
for ... for ..
x = func.SomeFunc(a, b, c);
}
But it appears that the function call is not inlined since func above is called via the interface and not via the sealed class.
I also tried the obvious approach:
abstract class MyAlgo {
protected abstract int SomeFunc(int a, int b, int c);
public void Run() {
// as RunMyGenericAlgo above
}
}
sealed class MyAlgoSomeFunc1 : MyAlgo {
protected override int SomeFunc(int a, int b, int c) {...}
}
and it did not inline either.
This program will however inline as desired (and runs about 50% faster):
class MyAlgo {
int SomeFunc(int a, int b, int c) {...}
public void Run() {
// as above
}
}
EDIT: To clarify, I also investigated using the MethodImpl attribute with AggressiveInlining, and it did not seem to help.
Is what I'm trying even possible in C# or do I have to copy/paste my algorithm for each implementation of my inner function?
To allow a method to be inlined, the implementation must be constant (e.g. not dependant on variables). So any form of a virtual/abstract/interface/delegate call is by definition a call that can never be inlined.
Therefore, the only way is to have a nonvirtual method call, or just paste the code in there.
There are some exceptions to this rule. For example, the JVM designers have the problem of all the Java methods being virtual by default, they have virtual call inlining. This will do something like:
//calling obj.MyVirtCall();
if (obj.Type == MyCommonType) {
//inlined code for MyCommonType.MyVirtCall();
} else {
obj.MyVirtCall();
}
Edit:
You could used T4 templates to generate C# code for each override of Run in your algorithm example, not requiring duplicate code, however it could make the maintenance slightly more complex, having to also maintain a T4 template instead of just C# code.