.NET en Linux: no solo una estrategia de marketing

[ad_1]

El desarrollo de soluciones .NET en Linux siempre ha sido un desafío, ya que Visual Studio de Microsoft requiere que Windows funcione. Después de trabajar en varios proyectos de .NET, decidí probar los límites del desarrollo de .NET en Linux. Este sencillo tutorial se centra en una aplicación ASP.NET MVC que utiliza SQL Server para mostrar lo elegante y eficaz que puede ser el desarrollo de .NET en mi sistema operativo favorito.

Índice
  1. entorno de desarrollo
  2. andamio proyecto
  3. portabilidad de aplicaciones
  4. el servicio de base de datos
  5. MVC: modelo
  6. MVC: controlador y vista
  7. Prueba de migración y aplicación
  8. .NET en Linux simplemente funciona
  9. Lectura adicional en el blog de ingeniería de Toptal:

entorno de desarrollo

En primer lugar, debemos asegurarnos de que las herramientas .NET y el SDK asociados con nuestro tipo particular de Linux se instalen utilizando la guía estándar de Microsoft.

Mi entorno de desarrollo preferido consta de un entorno de desarrollo integrado (IDE) basado en Windows, una potente herramienta de gestión y consulta de bases de datos, la propia base de datos y herramientas para crearla e implementarla. Utilizo las siguientes herramientas para lograr una funcionalidad sólida y una buena experiencia de programación:

Asegúrese de que estas herramientas estén instaladas correctamente antes de continuar con nuestra aplicación de muestra.

andamio proyecto

En esta aplicación de ejemplo, destacaremos el desarrollo y la funcionalidad de ASP.NET a través de una serie de casos de uso para un sistema hipotético de gestión de inventario de una zapatería. Al igual que con cualquier aplicación .NET nueva, debemos crear una solución y luego agregarle un proyecto. Podemos usar las herramientas CLI de .NET SDK para configurar nuestra nueva solución:

mkdir Shoestore && cd Shoestore
dotnet new sln

A continuación, cree un proyecto ASP.NET que incluya una clase principal explícita para mayor comodidad, ya que esta estructura de proyecto es más familiar para los desarrolladores de ASP.NET. Vamos a crear nuestro proyecto usando el patrón MVC:

mkdir Shoestore.mvc && cd Shoestore.mvc
dotnet new mvc --use-program-main=true

A continuación, agregue el proyecto a la solución:

# Go to the root of the solution
cd ..
dotnet sln add Shoestore.mvc/

Ahora tenemos una solución estándar y el proyecto ASP.NET que contiene. Antes de continuar, asegúrese de que todo esté construido:

cd Shoestore.mvc/
dotnet restore
dotnet build

Las buenas prácticas de desarrollo fomentan la colocación de servicios críticos y el tiempo de ejecución de la aplicación en contenedores Docker para mejorar la implementación y la portabilidad. Entonces, creemos un contenedor Docker simple para admitir nuestra aplicación.

portabilidad de aplicaciones

Las imágenes de Docker suelen apuntar a otra imagen principal de Docker como el punto de partida aceptado para las necesidades básicas, como los sistemas operativos y las soluciones básicas, incluidas las bases de datos. Siguiendo esta práctica recomendada de Docker, cree un Dockerfile y un Docker Compose para una configuración adecuada del servicio mientras hace referencia a las imágenes principales publicadas por Microsoft. Usamos etapas docker para mantener nuestra imagen pequeña. Las etapas nos permiten usar el SDK de .NET cuando construimos nuestra aplicación, por lo que el tiempo de ejecución de ASP.NET solo es necesario mientras nuestra aplicación se está ejecutando.

Crear el Shoestore.mvc Dockerfile con el siguiente contenido:

# Shoestore\Shoestore.mvc\Dockerfile
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /shoestore
COPY Shoestore.mvc/*.csproj ./
# Restore project packages
RUN dotnet restore
COPY Shoestore.mvc/* ./
# Create a release build
RUN dotnet build -c Release -o /app/build

# Run the application and make it available on port 80
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
EXPOSE 80
# Assets and views
COPY Shoestore.mvc/Views ./Views
COPY Shoestore.mvc/wwwroot ./wwwroot
COPY --from=build /app/build ./
ENTRYPOINT [ "dotnet", "Shoestore.mvc.dll" ]

A continuación creamos el docker-compose.yml Archivo en la raíz de nuestra solución. Inicialmente, solo contiene una referencia a nuestros servicios de aplicación. .Dockerfile:

# Shoestore/docker-compose.yml
version: "3.9"
services:
  web:
    build:
      context: .
      dockerfile: Shoestore.mvc/Dockerfile
    ports:
      - "8080:80"

También configuremos nuestro entorno con un archivo .dockerignore para asegurarnos de que solo los artefactos de compilación se copien en nuestra imagen.

Ahora que nuestro servicio de aplicación está inyectado y su entorno de ejecución está en funcionamiento, necesitamos crear nuestro servicio de base de datos y conectarlo a nuestra configuración de Docker.

el servicio de base de datos

Agregar Microsoft SQL Server a nuestra configuración de Docker es sencillo, especialmente porque estamos usando una imagen de Docker proporcionada por Microsoft sin modificarla. Agregue el siguiente bloque de configuración al final del docker-compose.yml Archivo de configuración de la base de datos:

  db:
    image: "mcr.microsoft.com/mssql/server"
    environment:
      SA_PASSWORD: "custom_password_123"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"

Aquí, ACCEPT_EULA evita que la instalación se detenga, y la nuestra ports -La configuración pasará el puerto predeterminado de SQL Server sin traducción. Con esto, nuestro archivo de redacción contiene tanto nuestro servicio de aplicación como nuestra base de datos.

Antes de personalizar el código de la aplicación, verifiquemos que nuestro entorno Docker esté funcionando:

# From the root of the solution
docker compose up --build

Suponiendo que no haya errores en el lanzamiento, nuestra aplicación de ejemplo incompleta debería estar disponible a través de un navegador web en la dirección local http://localhost:8080.

Ahora podemos centrarnos en la parte divertida: personalizar el código de la aplicación y asegurarnos de que los datos de la aplicación persistan en la base de datos de Microsoft SQL Server. Usaremos las herramientas Entity Framework (EF) y .NET SDK para conectar la aplicación a la base de datos y configurar el modelo, la vista, el controlador y la configuración de la aplicación que requiere EF.

Antes de que podamos especificar las herramientas que necesitamos, necesitamos crear una tool-manifest Expediente:

# From the root of the solution

dotnet new tool-manifest

Agregue las herramientas EF y SDK a este archivo con estos simples comandos:

dotnet tool install dotnet-ef
dotnet tool install dotnet-aspnet-codegenerator

Para verificar la instalación adecuada de estas herramientas, ejecute dotnet ef. Si aparece un unicornio, están instalados correctamente. siguiente carrera dotnet aspnet-codegenerator para probar las herramientas ASP.NET; la salida debe ser un bloque de uso CLI genérico.

Ahora podemos usar estas herramientas para crear nuestra aplicación.

MVC: modelo

La primera tarea al crear nuestra aplicación es crear el modelo. Dado que este modelo se agregará más tarde a la base de datos, incluiremos los paquetes MS SQL Server y EF en nuestro proyecto:

cd Shoestore.mvc/
dotnet add package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet restore

A continuación, cree un objeto de contexto de base de datos EF que determinará qué modelos se agregarán a la base de datos y permitirá que nuestro código acceda y consulte fácilmente estos datos de la base de datos.

Un... crear Data Directorio para albergar el código específico de EF y crear el ApplicationDBContext.cs Archivo con el siguiente contenido:

// Shoestore/Shoestore.mvc/Data/ApplicationDBContext.cs
using Microsoft.EntityFrameworkCore;

namespace Shoestore.mvc.Data;

public class ApplicationDBContext : DbContext
{
  public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options):base(options){}
}

A continuación, configure la cadena de conexión de la base de datos, que debe coincidir con las credenciales que hemos configurado en la nuestra. Dockerfile. Establecer el contenido de Shoestore/Shoestore.mvc/appsettings.json A lo siguiente:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Shoestore": "Server=db;Database=master;User=sa;Password=custom_password_123;"
  }
}

Con la cadena de conexión de la base de datos configurada y el contexto de la base de datos codificado, podemos codificar nuestra aplicación Main Función. Incluiremos el manejo de excepciones de la base de datos para facilitar la depuración del sistema. Además, dado que un error de .NET en el código generado está causando que el contenedor acoplable muestre nuestras vistas incorrectamente, debemos agregar un código específico a la configuración de nuestro servicio de visualización. Esto establecerá explícitamente las rutas de archivo a nuestra ubicación de visualización en nuestra imagen de Docker:

using Microsoft.EntityFrameworkCore;
using Shoestore.mvc.Data;

namespace Shoestore.mvc;

// ...

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        // Associate our EF database context and configure it with our connection string
        var connectionString = builder.Configuration.GetConnectionString("Shoestore");
        builder.Services.AddDbContext<ApplicationDBContext>(
            options => options.UseSqlServer(connectionString));
        // Middleware to catch unhandled exceptions and display a stack trace
        builder.Services.AddDatabaseDeveloperPageExceptionFilter();

        // Add services to the container.
        // ASP.NET has a known issue where the final built app doesn't know where the view
        // files are (in the Docker container). 
        // The fix is to specifically add view locations.
        builder.Services
            .AddControllersWithViews()
            .AddRazorOptions(options => {
                options.ViewLocationFormats.Add("/{1}/{0}.cshtml");
                options.ViewLocationFormats.Add("/Shared/{0}.cshtml");
            });

Saltar a IsDevelopment if -Instrucción en el mismo archivo para agregar un punto final de migración de base de datos a nuestro sistema cuando está en modo de desarrollo. Agrega uno else Declaración con el siguiente código:

        // Configure the HTTP request pipeline.
        if (!app.Environment.IsDevelopment())
        {
            // Leave the contents of the if block alone. These are hidden for clarity.
        } else {
            app.UseMigrationsEndPoint();
        }

A continuación, ejecute una prueba rápida para asegurarse de que los nuevos paquetes y los cambios en el código fuente se compilen correctamente:

// Go to mvc directory
cd Shoestore.mvc
dotnet restore
dotnet build

Ahora completemos el modelo con nuestros campos obligatorios creando el Shoestore.mvc\Models\Shoe.cs Expediente:

namespace Shoestore.mvc.Models;

public class Shoe {
    public int ID { get; set; }
    public string? Name { get; set; }
    public int? Price { get; set; }
    public DateTime CreatedDate { get; set; }
}

EF genera SQL basado en el modelo mapeado, su archivo de contexto y cualquier código EF en nuestra aplicación. Los resultados de SQL luego se traducen y se devuelven a nuestro código según sea necesario. Cuando añadimos el nuestro Shoe Adaptando el modelo al contexto de nuestra base de datos, EF sabe cómo traducir entre MS SQL Server y nuestra aplicación. Hagamos esto en el archivo de contexto de la base de datos, Shoestore/Shoestore.mvc/Data/ApplicationDBContext.cs:

using Microsoft.EntityFrameworkCore;
using Shoestore.mvc.Models;

namespace Shoestore.mvc.Data;

public class ApplicationDBContext : DbContext
{
  public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options) { }

    private DbSet<Shoe>? _shoe { get; set; }
    public DbSet<Shoe> Shoe {
        set => _shoe = value;
        get => _shoe ?? throw new InvalidOperationException("Uninitialized property" + nameof(Shoe));
    }
}

Finalmente, usaremos un archivo de migración de base de datos para llevar nuestro modelo a la base de datos. La herramienta EF crea un archivo de migración específico de MS SQL Server basado en el contexto de la base de datos y el modelo asociado (es decir, Shoe):

cd Shoestore.mvc/
dotnet ef migrations add InitialCreate

Esperemos para ejecutar nuestra migración hasta que tengamos un controlador y una vista configurada.

MVC: controlador y vista

Crearemos nuestro controlador utilizando la herramienta de generación de código ASP.NET. Esta herramienta es muy poderosa pero requiere ciertas clases auxiliares. Utilizar el Design Paquetes de estilo para la estructura básica del controlador y su integración EF. Agreguemos estos paquetes:

cd Shoestore.mvc\
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design && \
dotnet add package Microsoft.EntityFrameworkCore.Design && \
dotnet restore

Ahora, crear nuestro controlador predeterminado es tan simple como invocar el siguiente comando:

cd Shoestore.mvc\
dotnet dotnet-aspnet-codegenerator controller \
        -name ShoesController \
        -m Shoe \
        -dc ApplicationDBContext \
        --relativeFolderPath Controllers \
        --useDefaultLayout \
        --referenceScriptLibraries

Cuando el generador de código crea nuestro controlador, también crea una vista simple para ese controlador. Con nuestros conceptos básicos de MVC en su lugar, estamos listos para poner todo en marcha.

Prueba de migración y aplicación

Las migraciones de EF suelen ser un asunto simple, pero cuando Docker está involucrado, el proceso se vuelve más complejo. En el próximo artículo de nuestra serie, exploraremos la manera maravillosamente enrevesada en que funcionan estas migraciones en nuestra solución Docker, pero por ahora solo queremos que nuestra migración se ejecute.

Todos los archivos de configuración y migración están incluidos en nuestro repositorio. Clonemos el proyecto completo en nuestra máquina local y hagamos la migración:

git clone https://github.com/theZetrax/dot-net-on-linux.git
cd ./dot-net-on-linux
docker composer up

Que docker composer La operación crea nuestra aplicación, ejecuta la migración e inicia nuestra aplicación ASP.NET con el tiempo de ejecución de .NET. Para acceder a la solución continua, visite http://localhost:8080/Shoes.

Aunque la interfaz de nuestra aplicación es simple, demuestra la funcionalidad en todos los niveles, desde la vista hasta la base de datos.

.NET en Linux simplemente funciona

Consulte el repositorio completo para obtener una descripción general de nuestra solución. El siguiente artículo cubre nuestra migración en detalle, así como consejos y trucos para hacer que nuestras imágenes de Docker sean livianas.

.NET en Linux es más que una quimera: es una combinación viable de lenguaje, tiempo de ejecución y sistema operativo. Es posible que muchos desarrolladores que crecieron con Visual Studio no tengan mucha experiencia con la CLI de .NET, pero estas herramientas son efectivas y poderosas.

Lectura adicional en el blog de ingeniería de Toptal:

El blog de ingeniería de Toptal quisiera agradecer a Henok Tsegaye por revisar los ejemplos de código que aparecen en este artículo.

[ad_2]

Si quieres conocer otros artículos parecidos a .NET en Linux: no solo una estrategia de marketing puedes visitar la categoría Software.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir