美文网首页
Asp.Net Core 使用Generic 控制器

Asp.Net Core 使用Generic 控制器

作者: 寻找无名的特质 | 来源:发表于2021-11-19 06:02 被阅读0次

Asp.Net Core控制器一般情况下不使用泛型,因为在控制器初始化时无法确定泛型的具体类型。在有些情况下需要泛型控制器,必须下面这段代码,

[TypeFilter(typeof(ControllerExceptionFilterAttribute))]
    [Area("MyAdmin")]
    public class ManagementController<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken,
            TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
            TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto, TRoleClaimDto> : Controller
        where TUserDto : UserDto<TKey>, new()
        where TRoleDto : RoleDto<TKey>, new()
        where TUser : IdentityUser<TKey>
        where TRole : IdentityRole<TKey>
        where TKey : IEquatable<TKey>
        where TUserClaim : IdentityUserClaim<TKey>
        where TUserRole : IdentityUserRole<TKey>
        where TUserLogin : IdentityUserLogin<TKey>
        where TRoleClaim : IdentityRoleClaim<TKey>
        where TUserToken : IdentityUserToken<TKey>
        where TUsersDto : UsersDto<TUserDto, TKey>
        where TRolesDto : RolesDto<TRoleDto, TKey>
        where TUserRolesDto : UserRolesDto<TRoleDto, TKey>
        where TUserClaimsDto : UserClaimsDto<TUserClaimDto, TKey>
        where TUserProviderDto : UserProviderDto<TKey>
        where TUserProvidersDto : UserProvidersDto<TUserProviderDto, TKey>
        where TUserChangePasswordDto : UserChangePasswordDto<TKey>
        where TRoleClaimsDto : RoleClaimsDto<TRoleClaimDto, TKey>
        where TUserClaimDto : UserClaimDto<TKey>
        where TRoleClaimDto : RoleClaimDto<TKey>
    {
        private readonly IIdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken,
           TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
           TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto, TRoleClaimDto> _identityService;

        public ManagementController(IIdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken,
           TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
           TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto, TRoleClaimDto> identityService)
        {
            _identityService = identityService;
        }

由于依赖注入的服务是泛型类型,所以要求泛型控制器,这种情况下,需要在启动时设置泛型控制器。在StartUp中增加下面的代码:

  services.AddControllers(o =>
             {
                 o.Conventions.Add(new GenericControllerRouteConvention());
             }).ConfigureApplicationPartManager(m =>
             {
                 m.FeatureProviders.Add(new GenericTypeControllerFeatureProvider<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken,
                     TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
                     TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto, TRoleClaimDto>());
             });

这里为ApplicationPart增加新的控制器属性:


    public class GenericTypeControllerFeatureProvider<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken,
       TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
       TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto, TRoleClaimDto> : IApplicationFeatureProvider<ControllerFeature>
       where TUserDto : UserDto<TKey>, new()
       where TRoleDto : RoleDto<TKey>, new()
       where TUser : IdentityUser<TKey>
       where TRole : IdentityRole<TKey>
       where TKey : IEquatable<TKey>
       where TUserClaim : IdentityUserClaim<TKey>
       where TUserRole : IdentityUserRole<TKey>
       where TUserLogin : IdentityUserLogin<TKey>
       where TRoleClaim : IdentityRoleClaim<TKey>
       where TUserToken : IdentityUserToken<TKey>
       where TUsersDto : UsersDto<TUserDto, TKey>
       where TRolesDto : RolesDto<TRoleDto, TKey>
       where TUserRolesDto : UserRolesDto<TRoleDto, TKey>
       where TUserClaimsDto : UserClaimsDto<TUserClaimDto, TKey>
       where TUserProviderDto : UserProviderDto<TKey>
       where TUserProvidersDto : UserProvidersDto<TUserProviderDto, TKey>
       where TUserChangePasswordDto : UserChangePasswordDto<TKey>
       where TRoleClaimsDto : RoleClaimsDto<TRoleClaimDto, TKey>
       where TUserClaimDto : UserClaimDto<TKey>
       where TRoleClaimDto : RoleClaimDto<TKey>
    {
        public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
        {
            var currentAssembly = typeof(GenericTypeControllerFeatureProvider<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken,
                TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
                TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto, TRoleClaimDto>).Assembly;
            var controllerTypes = currentAssembly.GetExportedTypes()
                                                 .Where(t => typeof(ControllerBase).IsAssignableFrom(t) && t.IsGenericTypeDefinition)
                                                 .Select(t => t.GetTypeInfo());

            var type = this.GetType();
            var genericType = type.GetGenericTypeDefinition().GetTypeInfo();
            var parameters = genericType.GenericTypeParameters
                                        .Select((p, i) => new { p.Name, Index = i })
                                        .ToDictionary(a => a.Name, a => type.GenericTypeArguments[a.Index]);

            foreach (var controllerType in controllerTypes)
            {
                var typeArguments = controllerType.GenericTypeParameters
                                                  .Select(p => parameters[p.Name])
                                                  .ToArray();

                feature.Controllers.Add(controllerType.MakeGenericType(typeArguments).GetTypeInfo());
            }
        }
    }

这段代码中注册程序集中的泛型控制器。总结一下,需要将自定义类型转换为控制器,需要自定义一个类,继承IApplicationFeatureProvider<ControllerFeature>,在PopulateFeature中,将相关类型增加到控制器中。

相关文章

网友评论

      本文标题:Asp.Net Core 使用Generic 控制器

      本文链接:https://www.haomeiwen.com/subject/ntwazltx.html