Tisa.Infrastructure 2025.9.10.1120

dotnet add package Tisa.Infrastructure --version 2025.9.10.1120
                    
NuGet\Install-Package Tisa.Infrastructure -Version 2025.9.10.1120
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tisa.Infrastructure" Version="2025.9.10.1120" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tisa.Infrastructure" Version="2025.9.10.1120" />
                    
Directory.Packages.props
<PackageReference Include="Tisa.Infrastructure" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tisa.Infrastructure --version 2025.9.10.1120
                    
#r "nuget: Tisa.Infrastructure, 2025.9.10.1120"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tisa.Infrastructure@2025.9.10.1120
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tisa.Infrastructure&version=2025.9.10.1120
                    
Install as a Cake Addin
#tool nuget:?package=Tisa.Infrastructure&version=2025.9.10.1120
                    
Install as a Cake Tool

Tisa.Infrastructure

NuGet Version License

Библиотека инфраструктурных компонентов для .NET приложений, разработанная компанией ТИСА. Предоставляет готовые решения для аутентификации, авторизации, обработки запросов, логирования, кэширования и других инфраструктурных задач.

Возможности

  • Поддержка .NET 8.0, .NET 9.0 и .NET 10.0
  • Интеграция с FastEndpoints для создания API
  • Система Service Installers для автоматической регистрации сервисов
  • JWT аутентификация и авторизация на основе разрешений
  • CQRS паттерн с поддержкой Mediator
  • Глобальная обработка исключений
  • Логирование с Serilog
  • Кэширование данных
  • Event Bus для интеграционных событий
  • Валидация запросов с FluentValidation
  • Интеграция с Tisa.Common и Tisa.Domain

Установка

dotnet add package Tisa.Infrastructure

Основные компоненты

Service Installers - Автоматическая регистрация сервисов

Система Service Installers позволяет автоматически регистрировать сервисы из сборок.

Создание Service Installer
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Tisa.Infrastructure.Abstractions;

public class UserServiceInstaller : IServiceInstaller
{
    public void InstallServices(IServiceCollection services, IConfiguration configuration)
    {
        services.AddScoped<IUserService, UserService>();
        services.AddScoped<IUserRepository, UserRepository>();
    }
}
Регистрация всех Service Installers из сборки
using Microsoft.Extensions.DependencyInjection;
using Tisa.Infrastructure.Extensions;
using System.Reflection;

public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
    // Регистрация всех Service Installers из текущей сборки
    services.InstallServicesFromAssembly(Assembly.GetExecutingAssembly(), configuration);
}
Автоматическая регистрация сервисов по интерфейсам
using Tisa.Common.ServiceLifetimes;
using Tisa.Infrastructure.Extensions;

// Регистрация всех классов, реализующих ITransient
services.AddTransientAsMatchingInterface(Assembly.GetExecutingAssembly());

// Регистрация всех классов, реализующих IScoped
services.AddScopedAsMatchingInterface(Assembly.GetExecutingAssembly());

FastEndpoints - Создание API endpoints

Библиотека интегрирована с FastEndpoints для создания высокопроизводительных API.

Создание Endpoint
using FastEndpoints;
using Tisa.Common.Primitives;
using Tisa.Infrastructure.Endpoints;
using Tisa.Infrastructure.Messaging;

public class GetUserEndpoint : Endpoint<GetUserQuery>
{
    private readonly IMediator _mediator;

    public GetUserEndpoint(IMediator mediator)
    {
        _mediator = mediator;
    }

    public override void Configure()
    {
        Get("/api/users/{Id}");
        AllowAnonymous();
    }

    public override async Task HandleAsync(GetUserQuery request, CancellationToken cancellationToken)
    {
        Result<UserDto> result = await _mediator.Send(request, cancellationToken);

        if (result.IsFailure)
        {
            await new ResultProblem(result.Error, Request.Path, HttpContext.TraceIdentifier)
                .ExecuteAsync(HttpContext);
            return;
        }

        await SendOkAsync(result.Value, cancellationToken);
    }
}
Использование ResultProblem для обработки ошибок
using Tisa.Infrastructure.Endpoints;
using Tisa.Common.Errors;

public class CreateUserEndpoint : Endpoint<CreateUserCommand>
{
    public override async Task HandleAsync(CreateUserCommand request, CancellationToken cancellationToken)
    {
        var result = await _mediator.Send(request, cancellationToken);

        if (result.IsFailure)
        {
            var problem = new ResultProblem(
                result.Error,
                Request.Path,
                HttpContext.TraceIdentifier
            );
            
            await problem.ExecuteAsync(HttpContext);
            return;
        }

        await SendOkAsync(result.Value, cancellationToken);
    }
}

CQRS - Команды и запросы

Библиотека предоставляет интерфейсы для реализации паттерна CQRS с использованием Mediator.

Создание команды
using Tisa.Infrastructure.Messaging;
using Tisa.Common.Primitives;

public record CreateUserCommand(string Name, string Email) : ICommand<UserDto>;

public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand, UserDto>
{
    private readonly IUserRepository _repository;

    public CreateUserCommandHandler(IUserRepository repository)
    {
        _repository = repository;
    }

    public async ValueTask<Result<UserDto>> Handle(CreateUserCommand command, CancellationToken cancellationToken)
    {
        var user = new User(Guid.NewGuid(), command.Name, command.Email);
        await _repository.AddAsync(user, cancellationToken);
        
        return Result.Success(new UserDto(user.Id, user.Name, user.Email));
    }
}
Создание запроса
using Tisa.Infrastructure.Messaging;
using Tisa.Common.Primitives;

public record GetUserQuery(Guid Id) : IQuery<UserDto>;

public class GetUserQueryHandler : IQueryHandler<GetUserQuery, UserDto>
{
    private readonly IUserRepository _repository;

    public GetUserQueryHandler(IUserRepository repository)
    {
        _repository = repository;
    }

    public async ValueTask<Result<UserDto>> Handle(GetUserQuery query, CancellationToken cancellationToken)
    {
        var user = await _repository.GetByIdAsync(query.Id, cancellationToken);
        
        if (user == null)
        {
            return Result.Failure<UserDto>("Пользователь не найден");
        }

        return Result.Success(new UserDto(user.Id, user.Name, user.Email));
    }
}

Валидация запросов

Библиотека автоматически валидирует команды и запросы с помощью FluentValidation.

Создание валидатора
using FluentValidation;
using Tisa.Infrastructure.Messaging;

public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
{
    public CreateUserCommandValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty().WithMessage("Имя обязательно")
            .MaximumLength(100).WithMessage("Имя не должно превышать 100 символов");

        RuleFor(x => x.Email)
            .NotEmpty().WithMessage("Email обязателен")
            .EmailAddress().WithMessage("Неверный формат email");
    }
}
Регистрация валидаторов
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddMediator(options => options.ServiceLifetime = ServiceLifetime.Scoped);

Аутентификация и авторизация

Библиотека предоставляет расширения для настройки JWT аутентификации и авторизации на основе разрешений.

Настройка аутентификации
using Tisa.Infrastructure.Authentication;

public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
    services.AddAuthenticationInternal();
    
    // Настройка JWT в appsettings.json
    // {
    //   "Jwt": {
    //     "SecretKey": "your-secret-key",
    //     "Issuer": "your-issuer",
    //     "Audience": "your-audience",
    //     "ExpirationMinutes": 60
    //   }
    // }
}
Настройка авторизации
using Tisa.Infrastructure.Authorization;

public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
    services.AddAuthorizationInternal();
    
    // Регистрация сервиса разрешений
    services.AddScoped<IPermissionService, PermissionService>();
}
Использование в Endpoints
using Tisa.Authorization.Attributes;
using Tisa.Authorization.Abstractions;

public class GetUserEndpoint : Endpoint<GetUserQuery>
{
    public override void Configure()
    {
        Get("/api/users/{Id}");
        // Требуется аутентификация
        // Требуется разрешение UserRead
    }
}

Middleware

Библиотека предоставляет готовые middleware для обработки исключений и логирования.

Глобальная обработка исключений
using Tisa.Infrastructure.Extensions;

public void Configure(IApplicationBuilder app)
{
    app.UseGlobalExceptionHandler();
    // Другие middleware
}
Обогащение контекста логирования
using Tisa.Infrastructure.Extensions;

public void Configure(IApplicationBuilder app)
{
    app.UseLogContextEnrichment();
    // Другие middleware
}
Логирование запросов с Serilog
using Tisa.Infrastructure;

public void Configure(IApplicationBuilder app)
{
    app.UseSerilogRequestLogger();
    // Другие middleware
}

Event Bus - Интеграционные события

Система Event Bus для публикации и обработки интеграционных событий.

Создание интеграционного события
using Tisa.Infrastructure.EventsBus;

public class UserCreatedIntegrationEvent : IntegrationEvent
{
    public Guid UserId { get; }
    public string UserName { get; }
    public string UserEmail { get; }

    public UserCreatedIntegrationEvent(Guid userId, string userName, string userEmail)
    {
        UserId = userId;
        UserName = userName;
        UserEmail = userEmail;
    }
}
Обработчик интеграционного события
using Tisa.Infrastructure.EventsBus;

public class UserCreatedIntegrationEventHandler : IIntegrationEventHandler<UserCreatedIntegrationEvent>
{
    private readonly IEmailService _emailService;

    public UserCreatedIntegrationEventHandler(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public async Task Handle(UserCreatedIntegrationEvent integrationEvent, CancellationToken cancellationToken)
    {
        await _emailService.SendWelcomeEmailAsync(
            integrationEvent.UserEmail,
            integrationEvent.UserName,
            cancellationToken
        );
    }
}
Публикация события
using Tisa.Infrastructure.EventsBus;

public class UserService
{
    private readonly IEventBus _eventBus;

    public UserService(IEventBus eventBus)
    {
        _eventBus = eventBus;
    }

    public async Task CreateUserAsync(string name, string email, CancellationToken cancellationToken)
    {
        var user = new User(Guid.NewGuid(), name, email);
        // Сохранение пользователя
        
        var integrationEvent = new UserCreatedIntegrationEvent(user.Id, user.Name, user.Email);
        await _eventBus.PublishAsync(integrationEvent, cancellationToken);
    }
}

Кэширование

Интерфейс для работы с кэшем данных.

Использование кэша
using Tisa.Infrastructure.Caching;

public class UserService
{
    private readonly ICacheService _cache;
    private readonly IUserRepository _repository;

    public UserService(ICacheService cache, IUserRepository repository)
    {
        _cache = cache;
        _repository = repository;
    }

    public async Task<UserDto> GetUserAsync(Guid id, CancellationToken cancellationToken)
    {
        string cacheKey = $"user:{id}";
        
        var cachedUser = await _cache.GetAsync<UserDto>(cacheKey, cancellationToken);
        if (cachedUser != null)
        {
            return cachedUser;
        }

        var user = await _repository.GetByIdAsync(id, cancellationToken);
        var userDto = new UserDto(user.Id, user.Name, user.Email);
        
        await _cache.SetAsync(cacheKey, userDto, TimeSpan.FromMinutes(30), cancellationToken);
        
        return userDto;
    }
}

Работа с данными

Интерфейс для создания подключений к базе данных.

Использование IDbConnectionFactory
using Tisa.Infrastructure.Data;
using Dapper;

public class UserRepository
{
    private readonly IDbConnectionFactory _connectionFactory;

    public UserRepository(IDbConnectionFactory connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }

    public async Task<User> GetByIdAsync(Guid id, CancellationToken cancellationToken)
    {
        await using var connection = await _connectionFactory.OpenConnectionAsync();
        
        const string sql = "SELECT * FROM Users WHERE Id = @Id";
        var user = await connection.QueryFirstOrDefaultAsync<User>(
            sql,
            new { Id = id }
        );
        
        return user;
    }
}

Системные часы

Интерфейс для получения текущего времени (полезно для тестирования).

Использование IDateTimeProvider
using Tisa.Infrastructure.Clock;

public class OrderService
{
    private readonly IDateTimeProvider _dateTimeProvider;

    public OrderService(IDateTimeProvider dateTimeProvider)
    {
        _dateTimeProvider = dateTimeProvider;
    }

    public Order CreateOrder(string orderNumber)
    {
        return new Order(
            Guid.NewGuid(),
            orderNumber,
            _dateTimeProvider.UtcNow
        );
    }
}

Базовые контроллеры

Базовый контроллер для API с поддержкой Mediator.

Использование ApiController
using Tisa.Infrastructure.Controllers;
using Tisa.Infrastructure.Messaging;
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
public class UsersController : ApiController
{
    public UsersController(IMediator mediator) : base(mediator)
    {
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetUser(Guid id, CancellationToken cancellationToken)
    {
        var query = new GetUserQuery(id);
        var result = await Sender.Send(query, cancellationToken);

        if (result.IsFailure)
        {
            return BadRequest(result.Error);
        }

        return Ok(result.Value);
    }
}

Структура проекта

  • Abstractions/ - Базовые интерфейсы (IServiceInstaller, IResultProblem)
  • Authentication/ - Компоненты аутентификации (JWT, Claims)
  • Authorization/ - Компоненты авторизации (Policies, Permissions)
  • Behaviors/ - Поведения для Mediator (Validation, Logging)
  • Caching/ - Интерфейсы для кэширования
  • Clock/ - Системные часы
  • Controllers/ - Базовые контроллеры
  • Data/ - Работа с данными (IDbConnectionFactory)
  • Emails/ - Отправка email
  • Endpoints/ - Расширения для FastEndpoints (ResultProblem)
  • Errors/ - Ошибки API
  • EventsBus/ - Шина интеграционных событий
  • Exceptions/ - Исключения инфраструктуры
  • Extensions/ - Методы расширения
  • Messaging/ - CQRS интерфейсы (ICommand, IQuery)
  • Middleware/ - Промежуточное ПО (Exception Handler, Logging)
  • Options/ - Опции конфигурации
  • ServiceInstallers/ - Фабрика Service Installers

Полный пример настройки приложения

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using System.Reflection;
using Tisa.Infrastructure.Extensions;
using Tisa.Infrastructure.Authentication;
using Tisa.Infrastructure.Authorization;
using FluentValidation;
using Mediator;

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Регистрация сервисов
        builder.Services.AddControllers();
        
        // Регистрация всех Service Installers
        builder.Services.InstallServicesFromAssembly(
            Assembly.GetExecutingAssembly(),
            builder.Configuration
        );

        // Регистрация аутентификации и авторизации
        builder.Services.AddAuthenticationInternal();
        builder.Services.AddAuthorizationInternal();

        // Регистрация Mediator
        builder.Services.AddMediator(options => 
        {
            options.ServiceLifetime = ServiceLifetime.Scoped;
        });

        // Регистрация валидаторов
        builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());

        // Регистрация FastEndpoints
        builder.Services.AddFastEndpoints();

        var app = builder.Build();

        // Настройка middleware
        app.UseGlobalExceptionHandler();
        app.UseLogContextEnrichment();
        app.UseSerilogRequestLogger();
        
        app.UseAuthentication();
        app.UseAuthorization();
        
        app.UseFastEndpoints();
        app.MapControllers();

        app.Run();
    }
}

Требования

  • .NET 8.0, .NET 9.0 или .NET 10.0
  • Tisa.Common
  • FastEndpoints 7.1.1
  • FluentValidation 12.1.0
  • Mediator.Abstractions 3.0.1
  • Scrutor 6.1.0
  • Serilog 4.3.0
  • Dapper 2.1.66

Зависимости

Библиотека использует следующие пакеты:

  • FastEndpoints - для создания высокопроизводительных API
  • FluentValidation - для валидации запросов
  • Mediator.Abstractions - для реализации CQRS паттерна
  • Serilog - для логирования
  • Dapper - для работы с базой данных
  • Scrutor - для автоматической регистрации сервисов

Авторы

Команда разработчиков TISA

Лицензия

MIT License

Поддержка

Для получения поддержки или сообщения об ошибках, пожалуйста, напишите нам на support@tisn.ru

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Tisa.Infrastructure:

Package Downloads
Tisa.XrmApp

Базовые классы и компоненты приложений ТИСА для работы с использованием NetCore.

Tisa.BpmCore

Базовый клиент для доступа к данным BPMSoft в приложениях .NET Core.

GitHub repositories

This package is not used by any popular GitHub repositories.