C # - How to access inner class from external assembly

The presence of an assembly that I cannot change (vendor supplied), which has a method that returns an object type but actually has an internal type.

How can I access the fields and / or methods of an object from my assembly?

Keep in mind that I cannot change the assembly supplied by the supplier.

In essence, here is what I have:

From the supplier:

internal class InternalClass public string test; end class public class Vendor private InternalClass _internal; public object Tag {get{return _internal;}} end class 

From my assembly using the vendor assembly.

 public class MyClass { public void AccessTest() { Vendor vendor = new Vendor(); object value = vendor.Tag; // Here I want to access InternalClass.test } } 
+71
c # prototype class internal
May 28 '09 at
source share
5 answers

Without access to the type (and not "InternalsVisibleTo", etc.) you will have to use reflection. But the best question would be: should you access this data? This is not part of a public type contract ... it sounds to me as if it was being considered as an opaque object (for their purposes, not for you).

You described it as a public instance field; to get this through reflection:

 object obj = ... string value = (string)obj.GetType().GetField("test").GetValue(obj); 

If this property is actually (and not a field):

 string value = (string)obj.GetType().GetProperty("test").GetValue(obj,null); 

If it is not publicly available, you need to use the BindingFlags GetField / GetProperty overload.

Important aside : be careful with this reflection; the implementation may change in the next version (crack your code), or it may be confused (break your code), or you may not have enough "trust" (violation of your code). Are you viewing a template?

+69
May 28 '09 at 1:32 p.m.
source share
— -

I see only one case when you allow exposing your internal members to another assembly and this is intended for testing.

Saying that there is a way to allow Friend assemblies access to internal elements:

In the project's AssemblyInfo.cs file, you add a line for each assembly.

 [assembly: InternalsVisibleTo("name of assembly here")] 

this information is available here.

Hope this helps.

+164
Jun 12 '09 at 0:52
source share

Reflection

 using System.Reflection; Vendor vendor = new Vendor(); object tag = vendor.Tag; Type tagt = tag.GetType(); FieldInfo field = tagt.GetField("test"); string value = field.GetValue(tag); 

Use reasonable power. Remember to check for errors. :)

+3
May 28 '09 at 13:34
source share

I would like to claim that you cannot increase the original assembly - using Mono.Cecil, you can insert [InternalsVisibleTo(...)] into the 3pty assembly. Please note that there may be legal consequences - you mess with the assembly of 3 parties and technical consequences - if the assembly has a strong name, you need to either remove it or rewrite it using another key.

  Install-Package Mono.Cecil 

And a code like:

 static readonly string[] s_toInject = { // alternatively "MyAssembly, PublicKey=0024000004800000... etc." "MyAssembly" }; static void Main(string[] args) { const string THIRD_PARTY_ASSEMBLY_PATH = @"c:\folder\ThirdPartyAssembly.dll"; var parameters = new ReaderParameters(); var asm = ModuleDefinition.ReadModule(INPUT_PATH, parameters); foreach (var toInject in s_toInject) { var ca = new CustomAttribute( asm.Import(typeof(InternalsVisibleToAttribute).GetConstructor(new[] { typeof(string)}))); ca.ConstructorArguments.Add(new CustomAttributeArgument(asm.TypeSystem.String, toInject)); asm.Assembly.CustomAttributes.Add(ca); } asm.Write(@"c:\folder-modified\ThirdPartyAssembly.dll"); // note if the assembly is strongly-signed you need to resign it like // asm.Write(@"c:\folder-modified\ThirdPartyAssembly.dll", new WriterParameters { // StrongNameKeyPair = new StrongNameKeyPair(File.ReadAllBytes(@"c:\MyKey.snk")) // }); } 
+3
Jun 02 '17 at 13:03
source share

Well, you can’t. Internal classes cannot be visible outside their assembly, so there is no direct access to it directly - AFAIK, of course. The only way is to use late binding at run time through reflection, then you can indirectly refer to methods and properties from the inner class.

-3
May 28, '09 at 13:34
source share



All Articles