Whenever you compile your dotnet project, an assembly is generated. Depending upon your preference, it could be exe or dll file. Usually, whenever we want to use an assembly in other projects, we generate a dll file. Like any ohter dotnet assembly, it contains classes, structs, interfaces etc. All of these containing types are accessible depending upon their access modifier, which could be internal or public. Internal access modifier is used to define assembly scope. All the containing types by default are internal and are not accessible by any outside assembly. To make them accessible, you need to mark your containing type public. These containing types can only be marked as Public or Internal. You cannot mark them as private, protected, or protected internal.
In simple words, if you create a dll file containing a reusable class which is marked as Public, then you can use that class in all of your projects by providing reference to that dll. But if that class is marked as Internal, it will not be accessible by any outside assembly.