How to change a type's accessor with Mono.Cecil

1.2k views Asked by At

Is this possible?

I want to make a public class internal.

Thanks

1

There are 1 answers

3
poupou On

Possible ? Of course! It can be as simple as:

1) load the assembly;

2) find the type;

3) change it's visibility;

4) save the assembly

However you can end up with a very broken assembly. E.g. if the type T is now internal but is used in public fields, properties, methods... then peverify won't like it.

For the (open source) Moonlight project we used a Cecil-based tuner which removed and (in your case) internalized a lot of stuff so that Mono BCL (matching the MS full framework) could look like the Silverlight BCL.

I guess you to read the (MIT.X11 licensed) source code from the link below to get a fully working implementation of internalizing a type.

https://github.com/mono/mono/tree/master/mcs/tools/tuner

https://github.com/mono/moon/tree/master/class/tuning

EDIT mode details (copy/pasted/adapted) from MoonlightA11yProcessor.cs

    void MakeApiInternal ()
    {
        foreach (TypeDefinition type in _assembly.MainModule.Types) {
            if (type.IsPublic)
                type.IsPublic = false;

            if (type.HasMethods)
                foreach (MethodDefinition method in type.Methods.Where (m => !m.IsConstructor))
                    if (method.IsPublic)
                        method.IsAssembly = true;
        }
    }

That will make every public type in (already loaded) _assembly an internal type (including all non-constuctor methods). You just need to filter your own type (e.g. based on it's FullName property) and save it back.