Tengo un proyecto que publico como paquete MyNuget en un feed local. El proyecto hace referencia a un ThirdPartyNuget que tiene una clase estática pública ThirdPartyExtensions con métodos de extensión públicos sobre IQueryable .
Ahora, en mi solución principal hago referencia a MyNuget y NO hago referencia a ThirdPartyNuget . Aún así, Visual Studio 2022 muestra los métodos de extensión de ThirdPartyExtensions . ¿Por qué?
No espero esto, ya que considero a ThirdPartyNuget el detalle de implementación de MyNuget .
Los ensamblados en ThirdPartyNuget están ofuscados y la clase ThirdPartyExtensions se ve extraña ya que no tiene espacio de nombres. Esto es lo que veo en el depurador:
typeof(ThirdPartyExtensions).Name == typeof(ThirdPartyExtensions).FullName == "ThirdPartyExtensions" typeof(ThirdPartyExtensions).Namespace == null typeof(ThirdPartyExtensions).GUID == {00000000-0000-0000-0000-000000000000}¿Cuál es la mecánica de este comportamiento?
¿Cómo oculto la visibilidad de ThirdPartyExtensions en mi solución principal?
Si usa el formato PackageReference para las dependencias de su paquete, la etiqueta PrivateAsset en su MyNuget .csproj puede ser la solución.
https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets
Es posible que esté utilizando una dependencia únicamente como un arnés de desarrollo y es posible que no desee exponerla a proyectos que consumirán su paquete. En este escenario, puede usar los metadatos de PrivateAssets para controlar este comportamiento.
<PackageReference Include="ThirdPartyNuget" Version="1.0.0"> <PrivateAssets>compile</PrivateAssets> </PackageReference> O puede usar developmentDependency en packages.config como se describe en esta pregunta:
No incluya dependencias del archivo packages.config al crear el paquete NuGet
En términos de la pregunta: "¿por qué las dependencias públicas son la forma predeterminada?", Diría: hace la vida más fácil.
Es más fácil consumir paquetes con dependencias públicas. Y es más fácil hacerlos públicos si se trata de un comportamiento predeterminado.
Por ejemplo, muchos paquetes para desarrollo web dependían de Newtonsoft.json . Y para configurar la serialización, era necesario exponerlo. Otra opinión al respecto.
Probablemente los chicos de MS tengan algunas estadísticas al respecto. Pero no vi ningún artículo sobre eso. Solo lo recomiendan como la forma predeterminada.
En cuanto a su caso, no estoy seguro de haberlo reproducido correctamente.
En mi prueba he creado tres proyectos:
Un subpaquete con espacio de nombres predeterminado vacío.
Un paquete con referencia a SubPackage con atributo PrivateAssets.
Y project, que hace referencia a Package, pero no a SubPackage.
No compila si trato de usar extensiones. Pero imprime '2' en tiempo de ejecución, si uso el método GetNumber .
Y si he entendido la pregunta correctamente, es el resultado deseado.
Pero no estoy seguro, ¿funcionará para su paquete ThirdPartyNuget parcheado o no?
Si no declara un espacio de nombres para su clase, se usa el espacio de nombres global predeterminado. El espacio de nombres global es el espacio de nombres que contiene espacios de nombres y tipos que no están declarados dentro de un espacio de nombres con nombre. Ver aquí
Puede ver las clases que no tienen espacio de nombres usando una palabra clave global . La palabra clave global es el alias del espacio de nombres global solo cuando es el identificador de la izquierda del calificador :: . Para obtener más información, lea aquí
In my main solution I reference MyNuget and DO NOT reference ThirdPartyNuget . PERO su MyNuget hace referencia a ThirdPartyNuget . Significa que su proyecto también será referenciado a ThirdPartyNuget .
No es posible ocultar la visibilidad de las extensiones, PERO...
Su expectativa y objetivo se ve extraño. Sin embargo, puedes hacer algo como esto:
Si su objetivo es: no permitir el uso de ese método de extensiones en sus proyectos que usan MyNuget , puede crear las mismas clases de extensiones con un espacio de nombres vacío. Por ejemplo, el proyecto ThirdPartyNuget tiene esta extensión (sin espacio de nombres):
public static class ThirdPartyExtensions { public static void DoSome(this string value) { //Do some } } Simplemente cree la misma clase en MyNuget e intente usar esto en su proyecto. Obtendrá un error ambiguo del compilador :).
Por lo tanto, no lo ocultará, pero no permitirá usar esta extensión.