Mapbox
Map Style
Nuget
Tecnología, innovación y responsabilidad social
Este patrón nos ayuda mejorar la mantenibilidad y la capacidad de prueba. Con la correcta separación de intereses, nuestra lógica de negocio ya se puede concentrar en el negocio en sí y no preocuparse en operaciones de bajo nivel, como abrir una conexión a una base de datos o algún socket.
Este patrón nos habla de una capa intermedia entre la lógica de negocio y la fuente de datos, pero hay muchas formas de entenderlo así que exploremos algunos puntos.
Algunos extienden esto usando inyección de dependencias, otros se organizan usando espacios de nombre y otros hacen cosas diferentes. La resolución o complejidad de esto ya depende de los requisitos del proyecto o elección de cada uno.
Lo bueno de este asunto es que desde .NET 4.5 y C# 5, la programación asíncrona nos permite fácilmente lidear con esta clase de situaciones, un claro ejemplo sería la forma en que HttpClient trabaja, pero igual nos podemos encontrar con casos que no estan listos para esto, por eso ahora veremos como trabajar asíncronamente con Enterprise Library.
En el siguiente código podemos apreciar un controllador que devuelve una lista de elementos.
Unable to connect to the remote server
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
Lo primero que hay que hacer es crear o seleccionar un proyecto de librería de clases, para este ejemplo estoy usando un proyecto .NET Standard.
El segundo paso es configurar las propiedades del paquete, para ello vamos a propiedades del proyecto y nos ubicamos en la configuración de paquete. Aquí encontraremos los metadatos de nuestro de librería de clases. No todos los campos son obligatorios, solo asegúrense de tener un Id de paquete único.
Observemos que los campos de la licencia, proyecto y repositorio corresponden a un proyecto en GitHub y es que este proyecto lo he subido ahí. Probablemente se hagan preguntas sobre la licencia, pero no se precoupen por ello, porque si entramos a GitHub nos daremos cuenta que nos ayudan a generar uno.
Volviendo a los metadatos, solo queda mencionar que la imagen correspondiente al icono debes subirla a algun lado.
Ahora el tercer paso solo involucra hacer click en la opción empaquetar del proyecto, asegurándonos claro que este en Release.
Una vez hecho esto, solo confirmemos que nuestro paquete se generó correctamente.
El cuarto y último paso, consiste en ingresar a nuestra cuenta de nuget.org, para ello solo iniciemos sesión gratuitamente con nuestra cuenta de Microsoft. Una vez hecho eso seleccionemos la opción Subir Paquete y busquemos nuestro archivo.
Luego solo revisemos que los metadatos son los que corresponden y en la parte de documentación podemos hacer referencia a nuestro README.
Simplemente copiando y pegando el enlace que obtenemos al dar click en Raw. Confirmamos que la documentación es la nuestra y damos en publicar.
Ahora para que nuestro paquete este disponible para el mundo deben pasar algunas horas, si queremos actualizar la documentación, podemos darle edit package y hacemos algo muy similar a lo que hicimos hace un momento.
Si ahora desde nuestro perfil seleccionamos la opción ver listado de paquetes, nos daremos cuenta que no estará nuestra última versión ahí, hay que esperar.
Pero si tenemos una anterior, desde ahí podremos darnos cuenta en la parte inferior que nuestra última versión esta pasando por un proceso de validación.
“Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.”
“Las abstracciones no deben depender de detalles, son los detalles los que deben depender de abstracciones.”
Estoy seguro que en más de una ocasión han visto algo así:
Los clientes de un programa dado sólo deberían conocer de éste aquellos métodos que realmente usan, y no aquellos que no necesitan usar.
Para todas estas situaciones es importante tener en claro el Principio de Sustitución de Liskov, el cual sostiene lo siguiente:
Los subtipos deben ser sustituibles por sus tipos base.
Hace poco tuve que aprender a progamar para subir vídeos en Windows Phone. Al parecer habían un par de formas de hacerlo, así que a continuación compartiré la que me funcionó y la que creo que fue la mejor alternativa. Se aceptan sugerencias :)!
Para mi caso en especial todo gira alrededor de la siguiente clase:
En el proyecto Windows Phone, empezamos actualizando el WMAppManifest.xml para poder usar la cámara y el micrófono.
Luego de ello ya podemos definir nuestra pantalla como mejor creamos.
En mi caso quedo así:
Luego de definir la pantalla, viene el .cs en el cual hay que lidear con el estado de la cámara, no vayamos a usar recursos que ya estan en uso y con la orientación de nuestra aplicación. Para mi fue todo un lío llegar a terminar esta parte, es más, actualmente tiene un bug. Una estrella para quien lo encuentra.
En fin, luego de haber capturado correctamente la información y dando aceptar, nos ayudamos de una variable estática en el App.xaml.cs llamada PendingVideo y navegamos hacia atrás. Ya del otro lado, la usamos y limpiamos referencias innecesarias.
using System;
namespace CSharp6.CTP6
{
internal class Program
{
private static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("¡Hola XAML Development!");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("¡Viva C# 6.0!");
}
}
}
using static System.Console;
using static System.ConsoleColor;
namespace CSharp6.CTP6
{
internal class Program
{
private static void Main(string[] args)
{
ForegroundColor = Cyan;
WriteLine("¡Hola XAML Development!");
ForegroundColor = Green;
WriteLine("¡Viva C# 6.0!");
}
}
}
Muchas veces hemos usado literales de cadena para hacer referencia el nombre de una variable.
public static void Foo(string code)
{
if (code== null) throw new Exception("code");
//...
}
public static void Foo(string code)
{
if (code== null) throw new Exception(nameof(code));
//...
}
try
{
throw new System.Exception("Error");
}
catch (System.Exception ex) when (ex.Message == "ReallyBadError")
{
// :(
}
catch (System.Exception ex) when (ex.Message == "Error")
{
WriteLine("Boom!");
}
public static async void BoomAsync()
{
try
{
throw new Exception("Boom!");
}
catch
{
await Task.Delay(5000);
WriteLine("Esperaste 5 segundos");
}
finally
{
await Task.Delay(3000);
WriteLine("Esperaste 3 segundos");
}
}
//C# < 6.0
string txt1 = "Hola" + "Mundo";
string txt2 = string.Format("{0} {1}", "Hola", "Mundo");
//C# >= 6.0
string txt3 = "Mundo";
int habitantes = 8000;
Console.WriteLine($"En el {txt3}. Hay aproximadamente {habitantes + 1} millones de habitantes. {DateTime.Now:dd-MM-yyyy}");
public static string NullConditional(object obj)
{
return obj?.ToString();
}
Dictionary<string, string> data = new Dictionary<string, string>()
{
{ "Fruta", "Mandarina" },
{ "Disciplina", "Parkour" },
{ "Profesion", "Developer" }
};
Dictionary<string, string> data = new Dictionary<string, string>()
{
["Fruta"] = "Mandarina",
["Disciplina"] = "Parkour",
["Profesion"] = "Developer"
};
public class Usuario
{
public Usuario()
{
this.Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public readonly int code = 3;
public int Code
{
get { return code; }
}
}
public class Usuario
{
public Guid Id { get; set; } = Guid.NewGuid();
public int Code { get; } = 3;
}