Token导航 LogoToken导航TokenDH.com
运维和基础设施权限需确认github未标认证来源可访问clear审计通过

abp-infrastructure-patternsabp 基础设施模式

Agent Skill

abp-infrastructure-patterns 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,354

周安装

57

GitHub Stars

21

下载量

474
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:abp-infrastructure-patterns(abp 基础设施模式)
来源仓库:https://github.com/thapaliyabikendra/ai-artifacts
仓库路径:skills/abp-infrastructure-patterns
安装命令:
npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill abp-infrastructure-patterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill abp-infrastructure-patterns

简介

abp-infrastructure-patterns 提供 ABP 框架的跨切面关注点和基础设施模式支持。

  • 适用于 Codex、Claude、Cursor、Gemini CLI 中处理授权、权限定义和基础设施集成场景。
  • 通过 npx skills add 从 GitHub 仓库安装,可结合示例代码理解权限分组与策略设计。
  • 安装前需确认项目是否基于 ABP Framework,避免在不匹配环境中误用。
  • 涉及权限和基础设施时,应区分测试环境与生产环境,防止配置错误导致安全风险。

SKILL.md

ABP Infrastructure Patterns

Cross-cutting concerns and infrastructure patterns for ABP Framework.

Authorization & Permissions

Define Permissions

// Domain.Shared/Permissions/ClinicPermissions.cs
public static class ClinicPermissions
{
    public const string GroupName = "Clinic";

    public static class Patients
    {
        public const string Default = GroupName + ".Patients";
        public const string Create = Default + ".Create";
        public const string Edit = Default + ".Edit";
        public const string Delete = Default + ".Delete";
    }

    public static class Appointments
    {
        public const string Default = GroupName + ".Appointments";
        public const string Create = Default + ".Create";
        public const string Edit = Default + ".Edit";
        public const string Delete = Default + ".Delete";
        public const string ViewAll = Default + ".ViewAll";  // Admins only
    }
}

Register Permissions

// Application.Contracts/Permissions/ClinicPermissionDefinitionProvider.cs
public class ClinicPermissionDefinitionProvider : PermissionDefinitionProvider
{
    public override void Define(IPermissionDefinitionContext context)
    {
        var clinicGroup = context.AddGroup(ClinicPermissions.GroupName);

        var patients = clinicGroup.AddPermission(
            ClinicPermissions.Patients.Default,
            L("Permission:Patients"));

        patients.AddChild(ClinicPermissions.Patients.Create, L("Permission:Patients.Create"));
        patients.AddChild(ClinicPermissions.Patients.Edit, L("Permission:Patients.Edit"));
        patients.AddChild(ClinicPermissions.Patients.Delete, L("Permission:Patients.Delete"));

        var appointments = clinicGroup.AddPermission(
            ClinicPermissions.Appointments.Default,
            L("Permission:Appointments"));

        appointments.AddChild(ClinicPermissions.Appointments.Create, L("Permission:Appointments.Create"));
        appointments.AddChild(ClinicPermissions.Appointments.ViewAll, L("Permission:Appointments.ViewAll"));
    }

    private static LocalizableString L(string name)
        => LocalizableString.Create<ClinicResource>(name);
}

Use Permissions

// Declarative
[Authorize(ClinicPermissions.Patients.Create)]
public async Task<PatientDto> CreateAsync(CreatePatientDto input) { }

// Imperative
public async Task<AppointmentDto> GetAsync(Guid id)
{
    var appointment = await _appointmentRepository.GetAsync(id);

    if (appointment.DoctorId != CurrentUser.Id)
    {
        await AuthorizationService.CheckAsync(ClinicPermissions.Appointments.ViewAll);
    }

    return _mapper.AppointmentToDto(appointment);
}

// Check without throwing
public async Task<bool> CanCreatePatientAsync()
    => await AuthorizationService.IsGrantedAsync(ClinicPermissions.Patients.Create);

Background Jobs

Define Job

public class AppointmentReminderJob : AsyncBackgroundJob<AppointmentReminderArgs>, ITransientDependency
{
    private readonly IRepository<Appointment, Guid> _appointmentRepository;
    private readonly IEmailSender _emailSender;

    public AppointmentReminderJob(
        IRepository<Appointment, Guid> appointmentRepository,
        IEmailSender emailSender)
    {
        _appointmentRepository = appointmentRepository;
        _emailSender = emailSender;
    }

    public override async Task ExecuteAsync(AppointmentReminderArgs args)
    {
        var appointment = await _appointmentRepository.GetAsync(args.AppointmentId);

        await _emailSender.SendAsync(
            appointment.Patient.Email,
            "Appointment Reminder",
            $"You have an appointment on {appointment.AppointmentDate}");
    }
}

public class AppointmentReminderArgs
{
    public Guid AppointmentId { get; set; }
}

Enqueue Job

public async Task<AppointmentDto> CreateAsync(CreateAppointmentDto input)
{
    var appointment = await _appointmentManager.CreateAsync(/*...*/);

    // Schedule reminder 24 hours before
    var reminderTime = appointment.AppointmentDate.AddHours(-24);

    await _backgroundJobManager.EnqueueAsync(
        new AppointmentReminderArgs { AppointmentId = appointment.Id },
        delay: reminderTime - DateTime.Now);

    return _mapper.AppointmentToDto(appointment);
}

Distributed Events

Publish Event

// From entity (recommended for domain events)
public class Patient : AggregateRoot<Guid>
{
    public void Activate()
    {
        IsActive = true;
        AddDistributedEvent(new PatientActivatedEto
        {
            Id = Id,
            Name = Name,
            Email = Email
        });
    }
}

// From application service
public async Task ActivateAsync(Guid id)
{
    var patient = await _patientRepository.GetAsync(id);
    patient.Activate();

    // Or manually publish:
    await _distributedEventBus.PublishAsync(new PatientActivatedEto
    {
        Id = patient.Id,
        Name = patient.Name,
        Email = patient.Email
    });
}

Handle Event

public class PatientActivatedEventHandler :
    IDistributedEventHandler<PatientActivatedEto>,
    ITransientDependency
{
    private readonly IEmailSender _emailSender;
    private readonly ILogger<PatientActivatedEventHandler> _logger;

    public PatientActivatedEventHandler(
        IEmailSender emailSender,
        ILogger<PatientActivatedEventHandler> logger)
    {
        _emailSender = emailSender;
        _logger = logger;
    }

    public async Task HandleEventAsync(PatientActivatedEto eventData)
    {
        _logger.LogInformation("Patient activated: {Name}", eventData.Name);

        await _emailSender.SendAsync(
            eventData.Email,
            "Welcome",
            "Your patient account has been activated");
    }
}

Robust Event Handler (Idempotent + Multi-Tenant)

public class EntitySyncEventHandler :
    IDistributedEventHandler<EntityUpdatedEto>,
    ITransientDependency
{
    private readonly IRepository<Entity, Guid> _repository;
    private readonly IDataFilter _dataFilter;
    private readonly ILogger<EntitySyncEventHandler> _logger;

    public async Task HandleEventAsync(EntityUpdatedEto eto)
    {
        // Disable tenant filter for cross-tenant sync
        using (_dataFilter.Disable<IMultiTenant>())
        {
            try
            {
                _logger.LogInformation("Processing entity sync: {Id}", eto.Id);

                // Idempotency check
                var existing = await _repository.FirstOrDefaultAsync(
                    x => x.ExternalId == eto.ExternalId);

                if (existing != null)
                {
                    ObjectMapper.Map(eto, existing);
                    await _repository.UpdateAsync(existing);
                }
                else
                {
                    var entity = ObjectMapper.Map<EntityUpdatedEto, Entity>(eto);
                    await _repository.InsertAsync(entity);
                }

                _logger.LogInformation("Entity sync completed: {Id}", eto.Id);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Entity sync failed: {Id}", eto.Id);
                throw new UserFriendlyException($"Failed to sync entity: {ex.Message}");
            }
        }
    }
}

Multi-Tenancy

Cross-Tenant Operations

public class CrossTenantService : ApplicationService
{
    private readonly IDataFilter _dataFilter;
    private readonly ICurrentTenant _currentTenant;

    public async Task<List<PatientDto>> GetAllTenantsPatients()
    {
        using (_dataFilter.Disable<IMultiTenant>())
        {
            return await _patientRepository.GetListAsync();
        }
    }

    public async Task OperateOnTenant(Guid tenantId)
    {
        using (_currentTenant.Change(tenantId))
        {
            await DoTenantSpecificOperation();
        }
    }
}

Tenant-Specific Seeding

public async Task SeedAsync(DataSeedContext context)
{
    if (context.TenantId.HasValue)
        await SeedTenantDataAsync(context.TenantId.Value);
    else
        await SeedHostDataAsync();
}

Module Configuration

[DependsOn(
    typeof(ClinicDomainModule),
    typeof(AbpIdentityDomainModule),
    typeof(AbpPermissionManagementDomainModule))]
public class ClinicApplicationModule : AbpModule
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        PreConfigure<AbpIdentityOptions>(options =>
        {
            options.ExternalLoginProviders.Add<GoogleExternalLoginProvider>();
        });
    }

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpDistributedCacheOptions>(options =>
        {
            options.KeyPrefix = "Clinic:";
        });

        context.Services.AddTransient<IPatientAppService, PatientAppService>();
        context.Services.AddSingleton<ClinicApplicationMappers>();
    }

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        if (env.IsDevelopment())
            app.UseDeveloperExceptionPage();
    }
}

Object Extension

public static class ClinicModuleExtensionConfigurator
{
    public static void Configure()
    {
        ObjectExtensionManager.Instance.Modules()
            .ConfigureIdentity(identity =>
            {
                identity.ConfigureUser(user =>
                {
                    user.AddOrUpdateProperty<string>(
                        "Title",
                        property =>
                        {
                            property.Attributes.Add(new StringLengthAttribute(64));
                        });
                });
            });
    }
}

Best Practices

  1. Permissions - Define hierarchically (Parent.Child pattern)
  2. Background jobs - Use for long-running or delayed tasks
  3. Distributed events - Use for loose coupling between modules
  4. Idempotency - Check for existing before insert in event handlers
  5. Multi-tenancy - Use IDataFilter.Disable<IMultiTenant>() sparingly
  6. Module deps - Declare all dependencies explicitly

Related Skills

  • abp-entity-patterns - Domain layer patterns
  • abp-service-patterns - Application layer patterns
  • openiddict-authorization - OAuth implementation
  • distributed-events-advanced - Advanced event patterns

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Cursor

31.02%
按下载量换算147

Claude Code

25.26%
按下载量换算120

github-copilot

16.73%
按下载量换算79

mcpjam

12.86%
按下载量换算61

crush

7.45%
按下载量换算35

cline

3.62%
按下载量换算17

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

权限需确认

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills