views:

2441

answers:

4

There's something I want to customize in the System.Web.Script.Services.ScriptHandlerFactory and other .NET stuff inside an internal class. Unfortunately, it's an internal class. What options do I have when trying to customize a method in this class?

+4  A: 

You might find this recent article enlightening. Basically, it says that you can't override anything marked internal, and the source is about as authoritative as it gets. Best you can hope for is an extension method.

Joel Coehoorn
Eric Lippert's blog is an excellent resource, I've followed it for years.
Kev
+4  A: 

The internal keyword signifies that a unit of code (class, method, etc.) is "public" to the assembly it is in, but private to any other assembly.

Because you are not in the same assembly, you cannot do anything. If it wasn't internal you could use the new keyword on the method you're overriding (to hide the original implementation) when extending the class.

In short: you are to be SOL.

The only thing i can think of you could do is write a proxy class, where one of your private fields is the class you'd want to extend and you implement all it's methods and proxy their calls. that way you can still customize output, but you'd have to get your class used, and considering it's marked internal, i'm not sure that's possible without some serious hacking.

using System;
...
using System.Web.Script.Services

namespace MyGreatCompany.ScriptServices 
{
    public class MyScriptHandlerFactory /* implement all the interfaces */
    {
        private ScriptHandlerFactory internalFactory;
        public MyScriptHandlerFactory()
        {
            internalFactory = new ScriptHandlerFactory();
        }
        ...
    }
}

This could make what you want to accomplish possible, but it won't be pretty.

Kris
+1  A: 

I believe you can use Reflection to get around the access modifiers on a class, so perhaps you can use Reflection.Emit to generate a type that inherits from an internal type (but NOT the sealed modifier), though I can't find an example of this online.

This certainly works for accessing private members of classes, and probably for inheritance of non-sealed classes. But it doesn't help much if the target methods are not already marked virtual.

Rob Walker
It also probably only works when you're running under full trust. Any context which requires verification is going to fail when you violate access control.
Jon Skeet
This approach doesn't work either, with an exception like System.TypeLoadException : Method 'MyOverridingMethod' on type 'MyClass' from assembly 'MyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.
Sergii Volchkov
A: 

It depends on the assembly. This could possibly violate some licensing (although its similar to some sort of static linking), and maybe even make deployment a nightmare, but you could consider:

  • Decompile and copy the code over to your own project; modify as needed
  • Recompile/patch the assembly and add an "InternalsVisibleToAttribute"
MichaelGG