Allow component to be marked as @internal
This is technically a duplicate of both #21213 and #7051 but seeing as each of those are closed, I'm unable to provide my own feedback there, so I'm opening this new ticket.
I would like to request the ability to mark components with an internal accessibility.
Today, I can ensure that any type in a project isn't accessible outside the project by marking it as internal. This is a useful means of ensuring that those types not intended for use outside of their current utility stay this way. An ASP.NET Core website implemented with Blazor is little different in that while no one should ever be trying to reference the project as a means of accessing its various components, one might try to do so to access its various other types (e.g. POCOs, JSON converters and the like).
I went through my project and marked all my types as internal, but at the end of that effort ran into the issue that there appears no way of marking components the same. This is bad, as this means I've run into the issue where my generically-implemented components are now more accessible than the types that they're constrained to giving me a build error.
For example, given a class like the following:
internal class GenericTableState<T> where T : IRecord
{
//...
}
And then a component, GenericTable.razor, implementing this with a typeparam itself:
@typeparam TState where TState : GenericTableState<TItem>
Both of these get a red squiggly with the following error:
Inconsistent accessibility: constraint type 'GenericTableState<TItem>' is less accessible than 'GenericTable<TState, TItem>`
Having a means of marking the component as internal would both ensure that the component cannot be used outside of the project (good coding practice) and allow the project to build with consistent accessibility. Rather, until this is made available, I'm going to have to roll back all the accessibility modifiers throughout the rest of the project and set to public which will have resulted in significant lost time and effort.
I'd be perfectly fine with the @visibility internal syntax, though I'm afraid I can't think of a great situation in which I might ever need private unless I were doing something creative with inheritance and needed more of a private protected. Anyway, just having support for internal would be fine at this juncture. Thank you for your renewed consideration!
Hello! Any eta for this?
I'm surprised to see this isn't possible right now, since it should be so easy to implement, and it's so critical for library design. Consider this scenario: -I am providing a reusable component library -My component library has a base class used by several razor components, which is intended to be private or internal. -That base class has some methods and properties -Those methods and properties reference other types, with their own extensive network of associated types and methods.
I only want to expose a handful of razor components as the public surface of my API, but due to this limitation, I have to make my entire network of internal base classes and helper types public, since you can't have less visible types exposed with higher visibility.
This is an artificial limitation, since everything is built up via reflection anyway. Someone has already had a go at submitting a PR for this in the past: https://github.com/dotnet/aspnetcore/pull/24062/commits But nothing was done, with no discussion or rationale as to why. Could we please get an answer on whether there is a fundamental reason why this isn't viable, and if not, if there is at least notional support for adding this feature? As it stands, it creates a lot of problems for component authors. Anything exposed as public from a library forms part of its public API, whether it's intended for use or not. Forcing all razor components to be public introduces maintenance problems for component library authors, and makes libraries less usable by making the API less discoverable, and easier to misuse.
In addition: now we can inject services in public constructor so we have different behavior between DI in constructor and DI in properties which allow to use internal services...
Code analyzer CA1515: Consider making public types internal now also wants all my Blazor app's components to be internal. Others have reported this at https://github.com/dotnet/aspnetcore/discussions/58950.
The same problem exists for PageModels. A different use case, but it's probably the same type of bug and will have the same type of fix.