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
.Net: Simplest Way to Send Post with Data and Read Response
Does It Make Sense to Use "As" Instead of a Cast Even If There Is No Null Check
How to Programmatically Fill in a Form and 'Post' a Web Page
Tuples( or Arrays ) as Dictionary Keys in C#
Change Desktop Wallpaper Using Code in .Net
Write File from Assembly Resource Stream to Disk
Order of Event Handler Execution
Linq to Entities Does Not Recognize the Method Last. Really
How to Send Ctrl+C to a Process in C#
How to Make the Cursor Turn to the Wait Cursor
Multipart Forms from C# Client
How to Add Assembly References in Visual Studio Code
Algorithm for Simplifying Decimal to Fractions
How to Update a Table Using Oledb Parameters
How to Filter All HTML Tags Except a Certain Whitelist