Browse Source

Merge pull request #13692 from abpframework/auto-merge/rel-6-0/1279

Merge branch dev with rel-6.0
pull/13711/head
maliming 4 years ago
committed by GitHub
parent
commit
043aef7384
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs
  2. 16
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs
  3. 50
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/AbpLazyServiceProvider_Tests.cs
  4. 2
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  5. 3
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts
  6. 12
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts
  7. 4
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts

21
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs

@ -1,19 +1,13 @@
using System; using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.DependencyInjection; namespace Volo.Abp.DependencyInjection;
public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDependency [ExposeServices(typeof(IAbpLazyServiceProvider))]
public class AbpLazyServiceProvider : CachedServiceProviderBase, IAbpLazyServiceProvider, ITransientDependency
{ {
protected IDictionary<Type, object> CachedServices { get; set; }
protected IServiceProvider ServiceProvider { get; set; }
public AbpLazyServiceProvider(IServiceProvider serviceProvider) public AbpLazyServiceProvider(IServiceProvider serviceProvider)
: base(serviceProvider)
{ {
ServiceProvider = serviceProvider;
CachedServices = new Dictionary<Type, object>();
} }
public virtual T LazyGetRequiredService<T>() public virtual T LazyGetRequiredService<T>()
@ -23,7 +17,7 @@ public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDepende
public virtual object LazyGetRequiredService(Type serviceType) public virtual object LazyGetRequiredService(Type serviceType)
{ {
return CachedServices.GetOrAdd(serviceType, () => ServiceProvider.GetRequiredService(serviceType)); return GetService(serviceType);
} }
public virtual T LazyGetService<T>() public virtual T LazyGetService<T>()
@ -33,7 +27,7 @@ public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDepende
public virtual object LazyGetService(Type serviceType) public virtual object LazyGetService(Type serviceType)
{ {
return CachedServices.GetOrAdd(serviceType, () => ServiceProvider.GetService(serviceType)); return GetService(serviceType);
} }
public virtual T LazyGetService<T>(T defaultValue) public virtual T LazyGetService<T>(T defaultValue)
@ -53,6 +47,9 @@ public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDepende
public virtual object LazyGetService(Type serviceType, Func<IServiceProvider, object> factory) public virtual object LazyGetService(Type serviceType, Func<IServiceProvider, object> factory)
{ {
return CachedServices.GetOrAdd(serviceType, () => factory(ServiceProvider)); return CachedServices.GetOrAdd(
serviceType,
_ => new Lazy<object>(() => factory(ServiceProvider))
).Value;
} }
} }

16
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs

@ -5,21 +5,21 @@ namespace Volo.Abp.DependencyInjection;
public abstract class CachedServiceProviderBase public abstract class CachedServiceProviderBase
{ {
private readonly IServiceProvider _serviceProvider; protected IServiceProvider ServiceProvider { get; }
private readonly ConcurrentDictionary<Type, Lazy<object>> _cachedServices; protected ConcurrentDictionary<Type, Lazy<object>> CachedServices { get; }
protected CachedServiceProviderBase(IServiceProvider serviceProvider) protected CachedServiceProviderBase(IServiceProvider serviceProvider)
{ {
_serviceProvider = serviceProvider; ServiceProvider = serviceProvider;
_cachedServices = new ConcurrentDictionary<Type, Lazy<object>>(); CachedServices = new ConcurrentDictionary<Type, Lazy<object>>();
_cachedServices.TryAdd(typeof(IServiceProvider), new Lazy<object>(() => _serviceProvider)); CachedServices.TryAdd(typeof(IServiceProvider), new Lazy<object>(() => ServiceProvider));
} }
public virtual object GetService(Type serviceType) public virtual object GetService(Type serviceType)
{ {
return _cachedServices.GetOrAdd( return CachedServices.GetOrAdd(
serviceType, serviceType,
_ => new Lazy<object>(() => _serviceProvider.GetService(serviceType)) _ => new Lazy<object>(() => ServiceProvider.GetService(serviceType))
).Value; ).Value;
} }
} }

50
framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/AbpLazyServiceProvider_Tests.cs

@ -0,0 +1,50 @@
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Modularity;
using Volo.Abp.Testing.Utils;
using Xunit;
namespace Volo.Abp.DependencyInjection;
public class AbpLazyServiceProvider_Tests
{
[Fact]
public void LazyServiceProvider_Should_Cache_Services()
{
using (var application = AbpApplicationFactory.Create<TestModule>())
{
application.Initialize();
var lazyServiceProvider = application.ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>();
var transientTestService1 = lazyServiceProvider.LazyGetRequiredService<TransientTestService>();
var transientTestService2 = lazyServiceProvider.LazyGetRequiredService<TransientTestService>();
transientTestService1.ShouldBeSameAs(transientTestService2);
var testCounter = application.ServiceProvider.GetRequiredService<ITestCounter>();
testCounter.GetValue(nameof(TransientTestService)).ShouldBe(1);
}
}
[DependsOn(typeof(AbpTestBaseModule))]
private class TestModule : AbpModule
{
public TestModule()
{
SkipAutoServiceRegistration = true;
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddType<TransientTestService>();
}
}
private class TransientTestService : ITransientDependency
{
public TransientTestService(ITestCounter counter)
{
counter.Increment(nameof(TransientTestService));
}
}
}

2
npm/ng-packs/packages/identity/src/lib/components/users/users.component.html

@ -39,7 +39,7 @@
><div class="text-center"><i class="fa fa-pulse fa-spinner"></i></div ><div class="text-center"><i class="fa fa-pulse fa-spinner"></i></div
></ng-template> ></ng-template>
<form *ngIf="form; else loaderRef" [formGroup]="form" (ngSubmit)="save()"> <form *ngIf="form; else loaderRef" [blueprints]="blueprints" [formGroup]="form" (ngSubmit)="save()">
<ul ngbNav #nav="ngbNav" class="nav-tabs"> <ul ngbNav #nav="ngbNav" class="nav-tabs">
<li ngbNavItem> <li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a> <a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>

3
npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts

@ -61,6 +61,9 @@ export class UsersComponent implements OnInit {
entityDisplayName: string; entityDisplayName: string;
blueprints = { pattern: 'AbpIdentity::Volo.Abp.Identity:InvalidUserName[{{ actualValue }}]' };
trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index; trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index;
onVisiblePermissionChange = event => { onVisiblePermissionChange = event => {

12
npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts

@ -1,6 +1,7 @@
import { IdentityUserDto } from '@abp/ng.identity/proxy'; import {IdentityUserDto} from '@abp/ng.identity/proxy';
import { EntityAction } from '@abp/ng.theme.shared/extensions'; import { EntityAction } from '@abp/ng.theme.shared/extensions';
import { UsersComponent } from '../components/users/users.component'; import { UsersComponent } from '../components/users/users.component';
import {ConfigStateService, CurrentUserDto} from "@abp/ng.core";
export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUserDto>([ export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUserDto>([
{ {
@ -18,13 +19,18 @@ export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUser
component.openPermissionsModal(data.record.id, data.record.userName); component.openPermissionsModal(data.record.id, data.record.userName);
}, },
permission: 'AbpIdentity.Users.ManagePermissions', permission: 'AbpIdentity.Users.ManagePermissions',
}, }, {
{
text: 'AbpIdentity::Delete', text: 'AbpIdentity::Delete',
action: data => { action: data => {
const component = data.getInjected(UsersComponent); const component = data.getInjected(UsersComponent);
component.delete(data.record.id, data.record.name || data.record.userName); component.delete(data.record.id, data.record.name || data.record.userName);
}, },
visible: data => {
const userName = data.record.userName;
const configStateService = data.getInjected(ConfigStateService)
const currentUser = configStateService.getOne("currentUser") as CurrentUserDto;
return userName !== currentUser.userName;
},
permission: 'AbpIdentity.Users.Delete', permission: 'AbpIdentity.Users.Delete',
}, },
]); ]);

4
npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts

@ -3,13 +3,15 @@ import { getPasswordValidators } from '@abp/ng.theme.shared';
import { ePropType, FormProp } from '@abp/ng.theme.shared/extensions'; import { ePropType, FormProp } from '@abp/ng.theme.shared/extensions';
import { Validators } from '@angular/forms'; import { Validators } from '@angular/forms';
const onlyLetterAndNumberRegex = /^[a-zA-Z0-9]+$/;
export const DEFAULT_USERS_CREATE_FORM_PROPS = FormProp.createMany<IdentityUserDto>([ export const DEFAULT_USERS_CREATE_FORM_PROPS = FormProp.createMany<IdentityUserDto>([
{ {
type: ePropType.String, type: ePropType.String,
name: 'userName', name: 'userName',
displayName: 'AbpIdentity::UserName', displayName: 'AbpIdentity::UserName',
id: 'user-name', id: 'user-name',
validators: () => [Validators.required, Validators.maxLength(256)], validators: () => [Validators.required, Validators.maxLength(256), Validators.pattern(onlyLetterAndNumberRegex)],
}, },
{ {
type: ePropType.Password, type: ePropType.Password,

Loading…
Cancel
Save