开发者

Have anybody created an open source dynamic .NET class for exposing private functions/properties on another class?

开发者 https://www.devze.com 2023-02-23 04:38 出处:网络
And if so, I would very much like to use it. Does anybody have any pointers? My goal is to remove the need for _accessor projects in my test solution. I figured that if I created a dynamic class, it

And if so, I would very much like to use it. Does anybody have any pointers?

My goal is to remove the need for _accessor projects in my test solution. I figured that if I created a dynamic class, it should be possible to record what functions are applied to it and then replay these functions, using reflection, on another object. And with reflection we can call private functions. (I want the C# variant of C++'s #define private public.)

I think I would be able to do this myself, but why do it if I can reu开发者_Go百科se some code.


If you want to use this for unit testing consider to change your approach to unit testing. If you go down to every private method your tests are coupled very tight to the actual implementation.

Common problems using this approach are

  • Very fragile and hard to maintain tests
  • Your tests are very likely to mirror the behavior and code of your application
  • Essential behavior of your classes isn't obvious because of dozens of tests describing every detail

Every time you have to refactor some code you will have to change a bunch of tests, too. This will create a huge barrier to refactoring because of the time and pain it takes to fix all breaking tests. You even risk creating undesired behavior because you have to change so many tests that the original behavior is changed.

I would recommend writing tests testing the behavior of your classes. If you change the way this behavior is achieved you won't break tests at all and get the confirmation that your refactoring did not change the overall behavior.

Your tests will be much clearer and specify the really important parts of your design. This helps when refactoring, or if some one (may be even you after a couple of months) has to get into the code again.


You can use extensions to access dynamically to every private functions.

public static class ObjectEx
    {
        public static object CallPrivateFunc(this object obj,string funcName, params object[] args)
        {
            const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod;
            return obj.GetType().InvokeMember(funcName, bindingFlags, null, obj, args);
        }
    }

There the usage:

public class MyClass
    {
        private void  MyFunc(int a,string c)
        {
            Trace.WriteLine("MyFunc called a:" + a + " c:" + c);
        }
    }
...
myClass.CallPrivateFunc("MyFunc", 10, "c");
...


I tried to create the class myself, is this code sort of works for method calls:

public class UnPrivatify : DynamicObject
{
    private object _obj;

    public UnPrivatify(object obj)
    {
        _obj = obj;
    }

    public override bool TryInvokeMember(
        InvokeMemberBinder binder,
        Object[] args,
        out Object result)
    {
        Type t = _obj.GetType();

        result = t.InvokeMember(binder.Name,
            System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public,
            null,
            _obj,
            args);

        return true;
    }
}


The apache licensed Impromptu Interface has static functions that use the DLR to invoke methods or properties regards of whether it's private or not via binder.name. It should be pretty easy to call those inside of a DynamicObject.

http://code.google.com/p/impromptu-interface/wiki/UsageReallyLateBinding

Edit:

In the latest released version 4.0, there is a abstract class ImpromptuForwarder that if you make a plain subclass with no changes would forward dynamic calls to private methods/properties in the target.

0

精彩评论

暂无评论...
验证码 换一张
取 消