Accessibility in .Net Class Library - c#

I am working on a class Library and I'm having troubles with accessibility. My class library contains several internal classes which shouldn't be accessed from other applications. Instead I want to create a Singleton Main Class that contains Instances of all the internal classes, so other applications can access the Main class and then use the internal classes from that instance. The picture below explains the hierarchy.
I've tried making the Main Class public and the Internal Classes internal, however this gives me the error Error "Inconsistent accessibility". My Main Class looks like this:
public class Main
{
private static Main Instance;
public static Main GetInstance()
{
if (Instance == null)
Instance = new Main();
return Instance;
}
public Debugging Debugger = new Debugging();
}
And one of my Internal Classes (Debugging) looks like this:
internal class Debugging
{
Content....
}
So I'm hoping that someone can help me to figure out how to make the Internal Classes only accessible through my singleton Main Class.

I'm not positive from your question what your intent is so I'll break it into two options:
You want `Debugging` accessible to external assemblies, but only via `Main`
There are a few ways how to do this, but the simplest right now for you would be to keep Debugging public, but define only internal constructors. This will allow its usage but external assemblies won't be able to instantiate them, thus forcing them to access the instance created on Main
public class Debugging
{
internal Debugging() { }
}
You don't want `Debugging` accessible to external assemblies, and but still accessible within your class assembly via `Main`
Simply update the accessibility modifier for Main.Debugger to be internal
internal Debugging Debugger = new Debugging();

You have to set all of you class public if you have some public access to them (via the Main class).
Otherwise you can set the internal class as internal and provide a set of properties in the Main class (that wrap internal classes' fields/methods) in order to access their field/methods. You can set the constructors of internal class as internal in order to avoid those class instantiations.
In general: Every field/method exposed from a public class should have a public return type.
Some MSDN reference

If you need to access the Debugger class outside the Library you need to change the access modeifier to public. As suggested make the constructor as internal so no one outside the assembly can create an instance of those classes.

Related

How to call Internal class methods through Interface in DLL

In my Xamarin.iOS binding project's, I have following interface defined in my ApiDefinition.cs
[BaseType(typeof(LSMAHandler))]
[Protocol, Model]
interface LSMAHandlerRegister
It has generated LSMAHandlerRegister.g.cs in my project/obj/Debug/ios/project. This file contains followings
public interface ILSMAHandlerRegister : INativeObject,
IDisposable,SightCallBinding.ILSMAHandler
internal sealed class LSMAHandlerRegisterWrapper : BaseWrapper,
ILSMAHandlerRegister
public unsafe abstract partial class LSMAHandlerRegister :
LSMAHandler, ILSMAHandlerRegister
I have added the generated DLL to my xamarin.ios project. Now I want to call RegisterWithURL method in above class. But the implementation of that method only available in internal wrapper class. How can I call to this method within my Xamarin.iOS project?
Simple anwser - you can't. Internal classes are not visible in dll.
There are some things you can do though.
First of all think why this class is internal. There may be an important reason for this. The things you can do (you have to have access to this project)
make class and interfaces public (maybe there is no reason for it to be internal)
use InternalsVisibleTo https://learn.microsoft.com/pl-pl/dotnet/api/system.runtime.compilerservices.internalsvisibletoattribute?view=netframework-4.8 - note however, that this is considered a bad practice and should not be done. One exception is test project. You can show internals to test project. That maybe sometimes ok.
create other public class that make use of this internal one, for example:
public class MyPublicHelper
{
public void CallMyInternalMethod()
{
MyInternalClass obj = new MyInternalClass();
obj.MyInternalMethod();
}
}

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

I'm having a hard time making this work.
The 3 classes FooType, WebApp & IWebApp must not be accessbile \ visible outside of this DLL. So hence the sealed & internal classes.
Issues I'm having are ...
1) In WebApp class, FeeType1 is not accessible in RouteOneBuilder method's parameter.
2) In WebApp class, FeeType1 is not accessible \ visible in switch's case-statement. (need to be visible).
3) In WebApp class, CreditApplication of FeeType1 property is not visible in the switch's case-statement (need to be visible).
Is there a better way to this complicated script? Am I already screwed for exposing classes outside of this DLL? Can all of step 1 to 4 be resolved differently (or be fixed somehow)?
I don't see how can I make this any simplier.
internal static class FooType
{
public class FeeType
{
public FeeType() { }
public string CreditApplication = "Credit Application";
public string CreditVehicle = "Credit Vehicle";
}
public FeeType FeeType1
{
get { return new FeeType(); }
private set { }
}
}
sealed class WebApp : IWebApp
{
public string RouteOneBuilder(FooType.FeeType1 typing)
{
var xml = "";
switch(typing)
{
case FooType.FeeType1.CreditApplication:
xml = "asdf";
break;
default:
throw new Exception("Unknown value");
}
return xml;
}
}
internal interface IWebApp
{
string RouteOneBuilder(FooType.FeeType typing);
}
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.
The design is not correct.
If a type is marked as internal this indicates that it should never be accessed outside of its DLL. If this type must be accessed outside of the DLL in which it is declared, it should not be marked internal.
What constraint is preventing you from using a public modifier or from including the types in the same DLL as the consuming code?
In certain cases it is useful for external DLLs or EXEs to view internal members declared in another DLL. One notable case is for unit testing. The code under test may have an internal access modifier, but your test DLL still needs to access the code in order to test it. You can add the following to AssemblyInfo.cs of the project containing the internal members to allow external access.
[assembly:InternalsVisibleTo("Friend1a")]
See InternalsVisibleToAttribute Class for more details.
Side note: The sealed access modifier doesn't prevent access from outside of the declaring DLL. It prevents other types from extending the type.

Class creatable only within same file, other users can only reference it

This question is a continuation of the following question:
Basic OOPs related query
How can I ensure that OutputClass object can be created only inside the same file (api.cs), i.e.
OutputClass object1 = new ObjectClass(3);
Whereas the user of the API should not be able to create a new storage for this class, rather only be able to reference to it when it is provided from the API, i.e. the user of API should be able to do only the following:
OutputClass object1
whereas if he tries to create a new ObjectClass, it should not be possible.
You can make the constructor internal or private:
public class OutputClass
{
internal OutputClass()
{
}
}
internal means that it can be called from any class in the same assembly (not just the .CS file). private means that it can only be called from within that class (usually through a static factory method).
You can declare the constructor of OutputClass as private, assuming there is some mechanism within that class to create an instance. Otherwise an internal modifier might be more appropriate.
class OutputClass
{
private OutputClass()
{
// inaccessible to anything but OutputClass methods
}
}

Can extension access an internal method in same assembly and be used by externals?

In the following code snippet assuming both these classes are in the same assembly, can an external assembly call .DoSomethingToSomeClass(); on an OtherClass, or would this bark at me about security concerns?
public class SomeClass
{
internal void DoSomething()
{
//hah!
}
}
public static OtherClassExtension
{
public static DoSomethingToSomeClass(this OtherClass target)
{
new SomeClass().DoSomething();
}
}
That definitely works without security concerns. Imagine the world we'd live in if it didn't: Any public method you write would have to call only other public methods.
Access modifiers are there to give you a say in what portions of your class (and what classes you write) are directly accessible by calling code. The fact there is some chain where they could be executed isn't relevant.
This would not cause any security concerns on .Net's part, nor should it. In public methods you have to be able to use internal (/private/protected) members.
The solution to the potential security issues this might cause is: The developer making the public member has to know what they're doing.
"The internal keyword is an access modifier for types and type members. Internal types or members are accessible only within files in the same assembly" Taken from MSDN.
I don't see why not, this should work, and you are calling a public class thats calling an internal method within it's own assembly.
Don't see any problem with code provided, honestly.
May you can pass SomeClass like a parameter, but it's completely design decision.

Can you create private classes in C#?

This is a question for the .NET philosophers:
It is my understanding that Microsoft consciously denied use of private classes in C#. Why did they do this and what are their arguments for doing so?
I, for example, am building a large application that includes a reporting tool. This tool uses a lot of business objects that are used only within the reporting tool and not in other parts of the project. I want to encapsulate them for use only within the reporting tool itself.
Great decision is creating separate project in VS for this tool, and I'll do like that, but I'm interesting, what if I can't do this - for exmple our architecture wasn`t good enough, and we have big single project.
Behind "private class" I mean a class that can't be used in any other namespace, except its own.
My question was not - how can I simulate this, or do in another way. I'm just wondering, why not use private keyword with class keyword without any parent classes. I`m thinking there should be some reason, and I want to know it
Allowing classes to be private to a namespace would achieve no meaningful level of protection.
Any assembly in the world could simply reference your dll, and start writing code in your namespace which accesses your supposedly private classes.
I think that's possibly the answer you'd get from Microsoft.
There's a workaround for this, but you might not like it.
Instead of using a namespace to scope your classes, use a public static partial class:
Before:
namespace MyCompany.Foo {
class Bar { }
public class Baz { }
}
After:
namespace MyCompany {
public static partial class Foo {
private class Bar { }
public class Baz { }
}
}
This construct, like a namespace, can span multiple files in the same project. But unlike a namespace, it cannot "escape" from your project (other projects cannot define other members inside Foo).
There's an added advantage that you can have utility methods that seem to have no class for code inside Foo.
The disadvantage is that, to use your non-private classes outside of your fake namespace, you have to reference them inside Foo:
using MyCompany;
// ...
var baz = new Foo.Baz();
This can be mitigated by using an alias for the class:
using Baz = MyCompany.Foo.Baz;
// ...
var baz = new Baz();
But you'd have to do it for each non-private class that you want to use.
UPDATE
It's interesting to note that C# 6 will have static using statements, which could effectively improve this proposal to use a public static partial class as a "module". You would just "use" the "module" to access its types directly.
Hopefully, it will work like this:
using MyCompany.Foo;
// ...
var baz = new Baz();
Just as if Foo was a namespace.
You can create a private class, as a member of another type:
public class Outer {
// ...
private class Inner {
// ...
}
}
and Inner is only visible to members of Outer.
At the outermost level (i.e. in a namespace) private as per its definition would not make sense (since there is nothing to be private in). Instead use internal (visible to the containing assembly's members only).
You can define a private class, but it can only be used by its containing class.
If you want a class that is only visible within a particular assembly (DLL/EXE/etc.), then you should declare it as internal (Friend in VB)
True but you can get a pretty close simulation of this with internal classes and the internalsvisibletoAttribute if the namespace is split across multiple assemblies.
Also remember that a class within another can be private to the outer class. The outer class can be considered a namespace for this purpose.
So I guess you want to do this
namespace Baz
{
private class foo
{
private int _bar;
}
}
If yes. Then what is the purpose foo will server. At namespace can you be more restrictive than internal , and make any use of the class.If I could do this where will I use this .
That is why you have this compile time validation.
Now Inside a Public Class it makes sense to have a private class. I cannot explain it better this Private inner classes in C# - why aren't they used more often?.

Categories