How to Access an Internal Class from an External Assembly

How can I access an internal class from an external assembly?

Without access to the type (and no "InternalsVisibleTo" etc) you would have to use reflection. But a better question would be: should you be accessing this data? It isn't part of the public type contract... it sounds to me like it is intended to be treated as an opaque object (for their purposes, not yours).

You've described it as a public instance field; to get this via reflection:

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

If it is actually a property (not a field):

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

If it is non-public, you'll need to use the BindingFlags overload of GetField/GetProperty.

Important aside: be careful with reflection like this; the implementation could change in the next version (breaking your code), or it could be obfuscated (breaking your code), or you might not have enough "trust" (breaking your code). Are you spotting the pattern?

Access to internal classes from another project

You can use the InternalsVisibleTo attribute and provide the name of a specific assembly that can see the internal types in your assembly.

That being said.. I think you are bordering on over-designing this. If the Settings class belongs only to Assembly A... don't put it in Assembly B... put it in Assembly A.

Cannot access internal classes outside of DLL & certain public variables aren't accessible

Your definition of a sealed class is incorrect. It is not an access modifier like public, private, protected and internal. Marking a class sealed only says that it cannot be inherited from; it does not say anything about access per se.

From the MSDN documentation:

When applied to a class, the sealed modifier prevents other classes
from inheriting from it.

That means that you can still provide a public class that is sealed. However, if you try to inherit from a sealed class, you will receive a compiler error like this:

cannot derive from sealed type 'YourNamespace.YourSealedClass'.


Also, I suggest you read this and this regarding internal/public and nested classes.

Now, looking at the code you provided, the following compiler errors pop up:

FooType.FeeType1': cannot declare instance members in a static class

This error means that if the class is declared static, all of the members must be static too.

FooType.FeeType1' is a 'property' but is used like a 'type'

This arises from the fact that the class is static but none of the members are.

Inconsistent accessibility: parameter type 'FooType.FeeType' is less
accessible than method 'IWebApp.RouteOneBuilder(FooType.FeeType)'

The return type and each of the types referenced in the formal parameter list of a method must be at least as accessible as the method itself.

You can find more information about the last error here.

Can internal classes be accessed within other namespaces?

So this is the excerpt, right?

Java uses five explicit keywords to set the boundaries in a class: public,
private, protected, internal, and protected internal. Their use and
meaning are quite straightforward. These access specifiers determine who
can use the definitions that follow. public means the following
definitions are available to everyone. The private keyword, on the other
hand, means that no one can access those definitions except you, the
creator of the type, inside member functions of that type. private is a
brick wall between you and the client programmer. If someone tries to
access a private member, they’ll get a compile-time error. protected
acts like private, with the exception that an inheriting class has access to
protected members, but not private members. Inheritance will be
introduced shortly. internal is often called “friendly”–the definition can
be accessed by other classes in the same namespace as if it were public,
but is not accessible to classes in different namespaces. Namespaces will
be discussed in depth in chapter #ref# [sic]. protected internal allows
access by classes within the same namespace (as with internal) or by
inheriting classes (as with protected) even if the inheriting classes are
not within the same namespace.

C#’s default access, which comes into play if you don’t use one of the
aforementioned specifiers, is internal

The author is probably conflating Java's internal with c#'s internal.

They are slightly different, because Java does not have assemblies; it has packages, which organize classes into namespaces.

In c#, namespace has absolutely no relationship with accessibility modifiers. Only classes within the same assembly can access an internal type or member, unless you use the InternalsVisibleTo attribute. Namespace doesn't matter.

Cannot cast list of internal class from another assembly in C#

You should not expose an internal type from a public API...and you are returning an empty list from PublicMethod() so there is no InternalClass object to access.

But if the PublicMethod() actually returns an InternalClass object...:

public class PublicClass
{
public object PublicMethod()
{
return new List<InternalClass>() { new InternalClass() { b = 10 } };
}
}

...you could access its fields through reflection like this:

static void Main()
{
PublicClass P = new PublicClass();
System.Collections.IList list = P.PublicMethod() as System.Collections.IList;
object internalObject = list[0];
FieldInfo fi = internalObject.GetType().GetField("b", BindingFlags.NonPublic | BindingFlags.Instance);
byte b = (byte)fi.GetValue(internalObject);
Console.WriteLine(b);
}

The above sample code will print "10", i.e. the value of the byte "b" field of the InternalClass object returned from the PublicMethod(), to the Console.

How to access internal class using Reflection

In general, you shouldn't do this - if a type has been marked internal, that means you're not meant to use it from outside the assembly. It could be removed, changed etc in a later version.

However, reflection does allow you to access types and members which aren't public - just look for overloads which take a BindingFlags argument, and include BindingFlags.NonPublic in the flags that you pass.

If you have the fully qualified name of the type (including the assembly information) then just calling Type.GetType(string) should work. If you know the assembly in advance, and know of a public type within that assembly, then using typeof(TheOtherType).Assembly to get the assembly reference is generally simpler, then you can call Assembly.GetType(string).

how do I provide access to internal project classes through a DLL

You should move all classes that represents data for request and response to the MAIN module. You should also create interfaces in MAIN module that will specify API for submodules. In submodules reference MAIN module and implement interfaces.

In this design submodules only implement functionality that MAIN needs, all data structures and interfaces are in MAIN. If some interface should not be visible to the client code you should make it internal and use InternalsVisibleTo attribute on assembly level to share it with other submodules of your library but not with client code (more on that Make internal classes visible to others assemblies).



Related Topics



Leave a reply



Submit