Skip to main content

C# 4.0 AccessPrivateWrapper – Instantiate and Access Private/Internal Classes and Members via dynamic + reflection

[+] Download Related Source code

I love to see private thingsFrankly, intrusion in to the private space of others is not so great. Mostly, you’ll get a kick in your ass, but at times, if you are lucky and if you are really smart, you’ll end up finding something really cool (Bond, James Bond).

For me, at times, when doing some hacks/exploration of compiled or third party assemblies, I end up wanting to initialize a private class or a class with a private or internal constructor. Or, at times, when dealing with pre-compiled legacy libraries that I can’t change - I want to write a couple of tests against a private method to understand how it works.  I remember going through the source code of TFS power toys or so some time back - and I found that those guys are bringing up a lot of goodness by unearthing some private classes in the TFS library.

Still, I should warn you.

Warning (assume that this is in red): Private types, internals and private members are so because of some reason, and often you don’t want to mess with them directly. And if you do, chances are that you’ll break later, because there is no guarantee that the guys who created those assemblies will keep the private/internal implementations as such.

If you still don’t mind breaking the rules so that you can un earth some hidden potential against all the danger warnings - here is a quick wrapper class that’ll make the job easy using C# 4.0 dynamic features and reflection.  And more than that, this is a good learning point to see how you can use reflection to initialize private types, invoke private/internal constructors, get/set private properties, invoke private methods etc.

1 – What we are talking about

To explain further what we’ll achieve, consider this simple example.

 
class Program
    {
        static void Main(string[] args)
        {
            //Note that the type of 'wrapper' is dynamic
            dynamic wrapper =  new AccessPrivateWrapper(new ClassWithPrivateMembers()) ;

            //Let us access the private members
            wrapper.somePrivateField = "Field Val";
            wrapper.SomePrivateProperty = "Property Val";
            wrapper.DumpValues();

            Console.ReadLine();
        }

        class ClassWithPrivateMembers
        {
            private string somePrivateField;
            private string SomePrivateProperty { get; set; }

            private void DumpValues()
            {
                Console.WriteLine("Look ma, I'm accessing private members. Prop = "
                    + SomePrivateProperty + ", Fld=" + somePrivateField);
            }

        }
    }

And if you run that, you’ll find that the dynamic wrapper is correctly setting the the private field and property values, and then  invoking a private method in the class (DumpValues method), to print the result.

image

No, we are not yet happy. What about accessing private members in private classes in other assemblies? All right, you can use the FromType method of AccessPrivateWrapper to initialize a private/internal class in a different assembly - and you can initilize the class, even if it's constructor is internal or private. Assume that you have a class named 'ClassWithPrivateConstructor' in an assembly, and it is having a private constructor. And you want to create an instance of that, and to invoke some private members inside. This is what you can do.
            //Note that the wrapper is dynamic
            dynamic wrapper = AccessPrivateWrapper.FromType
                (typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");

            //Access the private members
            wrapper.PrivateMethodInPrivateClass();

2 – What the heck is AccessPrivateWrapper

If you are wondering what exactly is AccessPrivateWrapper – it is a simple class we inherited from the System.Dynamic.DynamicObject class.

But before that If the keyword ‘dynamic’s not not familiar to you, I really suggest you to read this article I wrote earlier - C# 4.0 dynamic keyword – Under the hood

Coming back to DynamicObject - In dynamic languages like Ruby, there is an interesting feature called method_missing. Method missing is where your method request will end if the method you called cannot be found.

In .NET 4.0, now you can bring in the same feature, by inheriting your object from the DynamicObject class. What this means is, you'll get notified when a method/property is invoked/accessed on your object. The DynamicObject class has a few cool methods for you to override. For now, we are only interested in these members:

  • TryInvokeMember - Provides the implementation of calling a member.
  • TrySetMember - Provides the implementation of setting a member.
  • TryGetMember - Provides the implementation of getting a member.

So, we are inheriting our AccessPrivateWrapper from the DynamicObject class, and overriding these methods to access private and public methods, properties and fields via reflection (I hope you know the fact that via reflection, you can invoke, set and get the values of even private and internal members).

Have a look at the implementation of AccessPrivateWrapper

/// <summary>
    /// A 10 minute wrapper to access private members, havn't tested in detail.
    /// Use under your own risk - amazedsaint@gmail.com
    /// </summary>
    public class AccessPrivateWrapper : DynamicObject
    {

        /// <summary>
        /// The object we are going to wrap
        /// </summary>
        object _wrapped;
        
        /// <summary>
        /// Specify the flags for accessing members
        /// </summary>
        static BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance 
            | BindingFlags.Static | BindingFlags.Public;

        /// <summary>
        /// Create a simple private wrapper
        /// </summary>
        public AccessPrivateWrapper(object o)
        {
            _wrapped = o;
        }

        /// <summary>
        /// Create an instance via the constructor matching the args 
        /// </summary>
        public static dynamic FromType(Assembly asm,string type,params object[] args)
        {

            var allt = asm.GetTypes();
            var t=allt.First(item=>item.Name==type);


            var types=from a in args
                      select a.GetType();

            //Gets the constructor matching the specified set of args
            var ctor = t.GetConstructor(flags, null, types.ToArray(), null);

            if (ctor != null)
            {
                var instance = ctor.Invoke(args);
                return new AccessPrivateWrapper(instance);
            }

            return null;
        }

        /// <summary>
        /// Try invoking a method
        /// </summary>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var types=from a in args
                      select a.GetType();

            var method = _wrapped.GetType().GetMethod
                (binder.Name,flags, null, types.ToArray(), null);

            if (method == null)
                return base.TryInvokeMember(binder, args, out result);
            else
            {
                result=method.Invoke(_wrapped, args);
                return true;
            }
        }

        /// <summary>
        /// Tries to get a property or field with the given name
        /// </summary>
        public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
        {
            //Try getting a property of that name
            var prop = _wrapped.GetType().GetProperty(binder.Name,flags);

            if (prop == null)
            {
                //Try getting a field of that name
                var fld = _wrapped.GetType().GetField(binder.Name, flags);
                if (fld != null)
                {
                    result = fld.GetValue(_wrapped);
                    return true;
                }
                else
                    return base.TryGetMember(binder, out result);
            }
            else
            {
                result = prop.GetValue(_wrapped, null);
                return true;
            }
        }

        /// <summary>
        /// Tries to set a property or field with the given name
        /// </summary>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var prop = _wrapped.GetType().GetProperty(binder.Name, flags);
            if (prop == null)
            {
                var fld = _wrapped.GetType().GetField(binder.Name, flags);
                if (fld != null)
                {
                    fld.SetValue(_wrapped,value);
                    return true;
                }
                else
                    return base.TrySetMember(binder, value);
            }
            else
            {
                prop.SetValue(_wrapped, value, null);
                return true;
            }
        }

    }

That looks simple, isn’t it? To detail that a bit, when ever user sets or gets a property or field on our dynamic object, the TrySetMember or TryGetMember will get called - and from there onwards, we use reflection to do the job of setting or getting the property or field value, regardless whether it is private or public. If a property of the given name doesn’t exist we’ll try to find a field of the given name to do the get or set operation.

Similarly, TryInvokeMethod will get fired when the user tries to invoke a method via our dynamic wrapper. We fetch the method matching the type of arguments, to obtain the correct overload, and then do the job via reflection. Make sure you download the code from the above link, and debug through a bit.

Also, pay some special attention to the FromType method that we used earlier. Basically, it’ll find the type to create an instance of, and then will find the constructor to invoke, based on the given arguments.

More Thoughts

Now, what about Unit testing your private members? Ever wanted to do that? That is not a common scenario, but at times, as I mentioned earlier, you might be dealing with a legacy system and you want to write a couple of tests against some of the private methods. Oh yes, you can use the AccessPrivateWrapper to do that.

Note that the above implementation don’t work with libraries that are obfuscated, because we are relying on reflection.

Also, the above implementation won’t access inherited private or internal members. That is pretty simple to implement, but that is an exercise for you ;)

Conclusion

A related tip: You can use InternalsVisibleTo attribute to grant access to the internal members of the target assembly to your caller assembly, if you’ve access to both the assemblies. This is useful, especially when you do unit testing.

Also, check out my other C# 4.0 dynamic tricks

 

Happy Coding!!

Shout it

Popular posts from this blog

Top 7 Coding Standards & Guideline Documents For C#/.NET Developers

Some time back, I collated a list of 7 Must Read, Free EBooks for .NET Developers, and a lot of people found it useful. So, I thought about putting together a list of Coding Standard guidelines/checklists for .NET /C# developers as well.As you may already know, it is easy to come up with a document - the key is in implementing these standards in your organization, through methods like internal trainings, Peer Reviews, Check in policies, Automated code review tools etc. You can have a look at FxCop and/or StyleCop for automating the review process to some extent, and can customize the rules based on your requirements.Anyway, here is a list of some good Coding Standard Documents. They are useful not just from a review perspective - going through these documents can definitely help you and me to iron out few hidden glitches we might have in the programming portion of our brain. So, here we go, the listing is not in any specific order.1 – IDesign C# Coding StandardsIDesign C# coding stand…

5 Awesome Learning Resources For Programmers (To help you and your kids to grow the geek neurons)

Happy New Year, this is my first post in 2012. I’ll be sharing few awesome learning resources I’ve bookmarked, and will be pointing out some specific computer/programming related courses I've found interesting from these resources.Also, thought about saving this blog post for my kids as well - instead of investing in these Child education schemes (though they are too small as of today, 2 years and 60 days respectively ). Anyway, personally my new year resolution is to see as much videos from this course collections (assuming I can find some free time in between my regular job && changing my babies diapers).1 – Khan AcademyAs I mentioned some time back, you and your kids are missing some thing huge if you havn’t heard about Khan Academy.  It is an awesome learning resource, especially if you want to re-visit your basics in Math, Science etc.With a library of over 2,600 videos covering everything from arithmetic to physics, finance, and history and 268 practice exercises, th…

Hack Raspberry Pi – How To Build Apps In C#, WinForms and ASP.NET Using Mono In Pi

Recently I was doing a bit of R&D related to finding a viable, low cost platform for client nodes. Obviously, I came across Raspberry Pi, and found the same extremely interesting. Now, the missing piece of the puzzle was how to get going using C# and .NET in the Pi. C# is a great language, and there are a lot of C# developers out there in the wild who are interested in the Pi.In this article, I’ll just document my findings so far, and will explain how develop using C# leveraging Mono in a Raspberry Pi. Also, we’ll see how to write few minimal Windows Forms & ASP.NET applications in the Pie as well.Step 1: What is Raspberry Pi?Raspberry Pi is an ARM/Linux box for just ~ $30. It was introduced with a vision to teach basic computer science in schools. How ever, it got a lot of attention from hackers all around the world, as it is an awesome low cost platform to hack and experiment cool ideas as Pi is almost a full fledged computer.  More About R-Pi From Wikipedia.The Raspberry Pi