diff --git a/docs/en/Migration-Guides/Abp-5_0-Angular.md b/docs/en/Migration-Guides/Abp-5_0-Angular.md
index 6cdb7af7c9..1188e68556 100644
--- a/docs/en/Migration-Guides/Abp-5_0-Angular.md
+++ b/docs/en/Migration-Guides/Abp-5_0-Angular.md
@@ -85,7 +85,7 @@ Following proxies have been affected:
### ChartComponent
-`ChartComponent` has moved from `@abp/ng.theme.shared` to `@abp/ng.components/chart.js`. To use the component, you need to import the `ChartModule` to your module as follows:
+[`ChartComponent`](../UI/Angular/Chart-Component.md) has moved from `@abp/ng.theme.shared` to `@abp/ng.components/chart.js`. To use the component, you need to import the `ChartModule` to your module as follows:
```ts
import { ChartModule } from '@abp/ng.components/chart.js';
diff --git a/docs/en/UI/Angular/Chart-Component.md b/docs/en/UI/Angular/Chart-Component.md
new file mode 100644
index 0000000000..a1cea80b52
--- /dev/null
+++ b/docs/en/UI/Angular/Chart-Component.md
@@ -0,0 +1,249 @@
+# Chart Component
+
+ABP Chart component exposed by `@abp/ng.components/chart.js` is based on [`charts.js`](https://www.chartjs.org/) v3+. You don't need to install the `chart.js` package. Since the `@abp/ng.components` is dependent on the `chart.js`, the package is already installed in your project.
+
+> Chart component loads `chart.js` script lazy. So it does not increase the bundle size.
+
+## How to Use
+
+First of all, need to import the `ChartModule` to your feature module as follows:
+
+```ts
+// your-feature.module.ts
+
+import { ChartModule } from '@abp/ng.components/chart.js';
+import { ChartDemoComponent } from './chart-demo.component';
+
+@NgModule({
+ imports: [
+ ChartModule,
+ // ...
+ ],
+ declarations: [ChartDemoComponent],
+ // ...
+})
+export class YourFeatureModule {}
+```
+
+Then, `abp-chart` component can be used. See an example:
+
+```ts
+// chart-demo.component.ts
+
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-chart-demo',
+ template: ` `,
+})
+export class ChartDemoComponent {
+ data = {
+ labels: ['Data 1', 'Data 2', 'Data 3'],
+ datasets: [
+ {
+ label: 'Dataset 1',
+ data: [40, 15, 45],
+ backgroundColor: ['#ff7675', '#fdcb6e', '#0984e3'],
+ },
+ ],
+ };
+}
+```
+
+> **Important Note**: Changing the chart data without creating a new data instance does not trigger change detection. In order to chart to redraw itself, a new data object needs to be created.
+
+See the result:
+
+
+
+## Examples
+
+### Doughnut
+
+```ts
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-chart-demo',
+ template: `
+
+ `,
+})
+export class ChartDemoComponent {
+ data = {
+ labels: ['Data 1', 'Data 2', 'Data 3'],
+ datasets: [
+ {
+ label: 'Dataset 1',
+ data: [40, 15, 45],
+ backgroundColor: ['#a0e6c3', '#f0ea4c', '#5b9dc3'],
+ },
+ ],
+ };
+
+ options = {
+ plugins: {
+ title: {
+ display: true,
+ text: 'Doughnut Chart',
+ fontSize: 16,
+ },
+ legend: {
+ position: 'bottom',
+ },
+ },
+ };
+}
+```
+
+Result:
+
+
+
+### Bar
+
+```ts
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-chart-demo',
+ template: `
+
+ `,
+})
+export class ChartDemoComponent {
+ data = {
+ labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
+ datasets: [
+ {
+ label: 'First dataset',
+ backgroundColor: '#42A5F5',
+ data: [65, 59, 80, 81, 56, 55, 40],
+ },
+ {
+ label: 'Second dataset',
+ backgroundColor: '#FFA726',
+ data: [28, 48, 40, 19, 86, 27, 90],
+ },
+ ],
+ };
+}
+```
+
+Result:
+
+
+
+### Radar
+
+```ts
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-chart-demo',
+ template: `
+
+
+
+ `,
+})
+export class ChartDemoComponent {
+ data = {
+ labels: [
+ 'January',
+ 'February',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December',
+ ],
+ datasets: [
+ {
+ label: 'Dataset 1',
+ backgroundColor: 'rgba(179,181,198,0.2)',
+ borderColor: 'rgba(179,181,198,1)',
+ data: [65, 59, 90, 81, 56, 55, 40, 35, 82, 51, 62, 95],
+ },
+ {
+ label: 'Dataset 2',
+ backgroundColor: 'rgba(255,99,132,0.2)',
+ borderColor: 'rgba(255,99,132,1)',
+ data: [28, 48, 40, 58, 96, 27, 100, 44, 85, 77, 71, 39],
+ },
+ ],
+ };
+
+ addDataset() {
+ this.data = {
+ ...this.data,
+ datasets: [
+ ...this.data.datasets,
+ {
+ label: 'Dataset 3',
+ backgroundColor: 'rgba(54,162,235,0.2)',
+ borderColor: 'rgba(54, 162, 235, 1)',
+ data: [90, 95, 98, 91, 99, 96, 89, 95, 98, 93, 92, 90],
+ },
+ ],
+ };
+ }
+}
+```
+
+Result:
+
+
+
+See the [`chart.js` samples](https://www.chartjs.org/docs/latest/samples) for more examples.
+
+## API
+
+### `abp-chart`
+
+#### Properties
+
+| Name | Description | Type | Default |
+| --------------- | ---------------------------------------------------------------- | ----------------------- | ------- |
+| `[type]` | Type of the chart. | `string` | null |
+| `[data]` | Chart data to display | `any` | null |
+| `[options]` | Chart options to customize | `any` | null |
+| `[plugins]` | Chart plugins to customize behaviour | `any` | null |
+| `[width]` | Witdh of the chart | `string` | null |
+| `[height]` | Height of the chart | `string` | null |
+| `[responsive]` | Whether the chart is responsive | `boolean` | true |
+| `(dataSelect)` | A callback that executes when an element on the chart is clicked | `EventEmitter` | - |
+| `(initialized)` | A callback that executes when the chart is initialized | `EventEmitter` | - |
+
+#### Methods
+
+| Name | Description | Parameters |
+| ---------------- | ------------------------------------------------------------------- | ---------- |
+| `refresh` | Redraws the chart | - |
+| `reinit` | Destroys the chart then creates it again | - |
+| `getBase64Image` | Returns a base 64 encoded string of the chart in it's current state | - |
+| `generateLegend` | Returns an HTML string of a legend for the chart | - |
+| `getCanvas` | Returns the canvas HTML element | - |
diff --git a/docs/en/UI/Angular/Permission-Management.md b/docs/en/UI/Angular/Permission-Management.md
index b8125bb2a3..dd373d6274 100644
--- a/docs/en/UI/Angular/Permission-Management.md
+++ b/docs/en/UI/Angular/Permission-Management.md
@@ -4,8 +4,6 @@ A permission is a simple policy that is granted or prohibited for a particular u
You can get permission of authenticated user using `getGrantedPolicy` or `getGrantedPolicy$` method of `PermissionService`.
-> ConfigState's getGrantedPolicy selector and ConfigStateService's getGrantedPolicy method deprecated. Use permission service's `getGrantedPolicy$` or `getGrantedPolicy`methods instead
-
You can get permission as boolean value:
```js
@@ -77,4 +75,46 @@ const routes: Routes = [
];
```
-Granted Policies are stored in the `auth` property of `ConfigState`.
\ No newline at end of file
+## Customization
+
+In some cases, a custom permission management may be needed. All you need to do is to replace the service with your own. Here is how to achieve this:
+
+- First, create a service of your own. Let's call it `CustomPermissionService` and extend `PermissionService` from `@abp/ng.core` as follows:
+
+```js
+import { ConfigStateService, PermissionService } from '@abp/ng.core';
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class CustomPermissionService extends PermissionService {
+ constructor(configStateService: ConfigStateService) {
+ super(configStateService);
+ }
+
+ // This is an example to show how to override the methods
+ getGrantedPolicy$(key: string) {
+ return super.getGrantedPolicy$(key);
+ }
+}
+```
+
+- Then, in `app.module.ts`, provide this service as follows:
+
+```js
+@NgModule({
+ // ...
+ providers: [
+ // ...
+ {
+ provide: PermissionService,
+ useExisting: CustomPermissionService,
+ },
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+That's it. Now, when a directive/guard asks for `PermissionService` from angular, it will inject your service.
diff --git a/docs/en/UI/Angular/images/bar-chart.png b/docs/en/UI/Angular/images/bar-chart.png
new file mode 100644
index 0000000000..58e4b85d03
Binary files /dev/null and b/docs/en/UI/Angular/images/bar-chart.png differ
diff --git a/docs/en/UI/Angular/images/doughnut-chart.png b/docs/en/UI/Angular/images/doughnut-chart.png
new file mode 100644
index 0000000000..8249b30164
Binary files /dev/null and b/docs/en/UI/Angular/images/doughnut-chart.png differ
diff --git a/docs/en/UI/Angular/images/pie-chart.png b/docs/en/UI/Angular/images/pie-chart.png
new file mode 100644
index 0000000000..c4a9c86750
Binary files /dev/null and b/docs/en/UI/Angular/images/pie-chart.png differ
diff --git a/docs/en/UI/Angular/images/radar-chart.gif b/docs/en/UI/Angular/images/radar-chart.gif
new file mode 100644
index 0000000000..8f8eae042b
Binary files /dev/null and b/docs/en/UI/Angular/images/radar-chart.gif differ
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 398da988e4..76e3f70d1c 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -1079,6 +1079,10 @@
{
"text": "Page",
"path": "UI/Angular/Page-Component.md"
+ },
+ {
+ "text": "Chart",
+ "path": "UI/Angular/Chart-Component.md"
}
]
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantController.cs
index 712a768137..c0dfeecfc1 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantController.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantController.cs
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
+using Volo.Abp.AspNetCore;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.MultiTenancy;
@@ -10,7 +11,7 @@ namespace Pages.Abp.MultiTenancy
[Area("abp")]
[RemoteService(Name = "abp")]
[Route("api/abp/multi-tenancy")]
- public class AbpTenantController : AbpController, IAbpTenantAppService
+ public class AbpTenantController : AbpControllerBase, IAbpTenantAppService
{
private readonly IAbpTenantAppService _abpTenantAppService;
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerBase.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerBase.cs
new file mode 100644
index 0000000000..20ad62991f
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerBase.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Mvc.Validation;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Features;
+using Volo.Abp.Guids;
+using Volo.Abp.Localization;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.ObjectMapping;
+using Volo.Abp.Timing;
+using Volo.Abp.Uow;
+using Volo.Abp.Users;
+
+namespace Volo.Abp.AspNetCore.Mvc
+{
+ public abstract class AbpControllerBase : ControllerBase, IAvoidDuplicateCrossCuttingConcerns
+ {
+ public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
+
+ protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService();
+
+ protected Type ObjectMapperContext { get; set; }
+ protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider =>
+ ObjectMapperContext == null
+ ? provider.GetRequiredService()
+ : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext)));
+
+ protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance);
+
+ protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService();
+
+ protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
+
+ protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService();
+
+ protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService();
+
+ protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService();
+
+ protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current;
+
+ protected IClock Clock => LazyServiceProvider.LazyGetRequiredService();
+
+ protected IModelStateValidator ModelValidator => LazyServiceProvider.LazyGetRequiredService();
+
+ protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService();
+
+ protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService();
+
+ protected IStringLocalizer L
+ {
+ get
+ {
+ if (_localizer == null)
+ {
+ _localizer = CreateLocalizer();
+ }
+
+ return _localizer;
+ }
+ }
+ private IStringLocalizer _localizer;
+
+ protected Type LocalizationResource
+ {
+ get => _localizationResource;
+ set
+ {
+ _localizationResource = value;
+ _localizer = null;
+ }
+ }
+ private Type _localizationResource = typeof(DefaultResource);
+
+ public List AppliedCrossCuttingConcerns { get; } = new List();
+
+ protected virtual IStringLocalizer CreateLocalizer()
+ {
+ if (LocalizationResource != null)
+ {
+ return StringLocalizerFactory.Create(LocalizationResource);
+ }
+
+ var localizer = StringLocalizerFactory.CreateDefaultOrNull();
+ if (localizer == null)
+ {
+ throw new AbpException($"Set {nameof(LocalizationResource)} or define the default localization resource type (by configuring the {nameof(AbpLocalizationOptions)}.{nameof(AbpLocalizationOptions.DefaultResourceType)}) to be able to use the {nameof(L)} object!");
+ }
+
+ return localizer;
+ }
+
+ protected virtual void ValidateModel()
+ {
+ ModelValidator?.Validate(ModelState);
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs
index 89282110b9..4947008411 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
[Area("abp")]
[RemoteService(Name = "abp")]
[Route("api/abp/application-configuration")]
- public class AbpApplicationConfigurationController : AbpController, IAbpApplicationConfigurationAppService
+ public class AbpApplicationConfigurationController : AbpControllerBase, IAbpApplicationConfigurationAppService
{
private readonly IAbpApplicationConfigurationAppService _applicationConfigurationAppService;
private readonly IAbpAntiForgeryManager _antiForgeryManager;
diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
index b747a858d2..ad857ad967 100644
--- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
using Confluent.Kafka;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
-using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Guids;
@@ -22,7 +21,6 @@ namespace Volo.Abp.EventBus.Kafka
[ExposeServices(typeof(IDistributedEventBus), typeof(KafkaDistributedEventBus))]
public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDependency
{
- protected AbpEventBusOptions AbpEventBusOptions { get; }
protected AbpKafkaEventBusOptions AbpKafkaEventBusOptions { get; }
protected IKafkaMessageConsumerFactory MessageConsumerFactory { get; }
protected IKafkaSerializer Serializer { get; }
@@ -30,7 +28,6 @@ namespace Volo.Abp.EventBus.Kafka
protected ConcurrentDictionary> HandlerFactories { get; }
protected ConcurrentDictionary EventTypes { get; }
protected IKafkaMessageConsumer Consumer { get; private set; }
- protected string DeadLetterTopicName { get; }
public KafkaDistributedEventBus(
IServiceScopeFactory serviceScopeFactory,
@@ -41,26 +38,20 @@ namespace Volo.Abp.EventBus.Kafka
IOptions abpDistributedEventBusOptions,
IKafkaSerializer serializer,
IProducerPool producerPool,
- IEventErrorHandler errorHandler,
- IOptions abpEventBusOptions,
IGuidGenerator guidGenerator,
IClock clock)
: base(
serviceScopeFactory,
currentTenant,
unitOfWorkManager,
- errorHandler,
abpDistributedEventBusOptions,
guidGenerator,
clock)
{
AbpKafkaEventBusOptions = abpKafkaEventBusOptions.Value;
- AbpEventBusOptions = abpEventBusOptions.Value;
MessageConsumerFactory = messageConsumerFactory;
Serializer = serializer;
ProducerPool = producerPool;
- DeadLetterTopicName =
- AbpEventBusOptions.DeadLetterName ?? AbpKafkaEventBusOptions.TopicName + "_dead_letter";
HandlerFactories = new ConcurrentDictionary>();
EventTypes = new ConcurrentDictionary();
@@ -70,7 +61,6 @@ namespace Volo.Abp.EventBus.Kafka
{
Consumer = MessageConsumerFactory.Create(
AbpKafkaEventBusOptions.TopicName,
- DeadLetterTopicName,
AbpKafkaEventBusOptions.GroupId,
AbpKafkaEventBusOptions.ConnectionName);
Consumer.OnMessageReceived(ProcessEventAsync);
@@ -88,12 +78,12 @@ namespace Volo.Abp.EventBus.Kafka
}
string messageId = null;
-
+
if (message.Headers.TryGetLastBytes("messageId", out var messageIdBytes))
{
messageId = System.Text.Encoding.UTF8.GetString(messageIdBytes);
}
-
+
if (await AddToInboxAsync(messageId, eventName, eventType, message.Value))
{
return;
@@ -101,18 +91,7 @@ namespace Volo.Abp.EventBus.Kafka
var eventData = Serializer.Deserialize(message.Value, eventType);
- await TriggerHandlersAsync(eventType, eventData, errorContext =>
- {
- var retryAttempt = 0;
- if (message.Headers.TryGetLastBytes(EventErrorHandlerBase.RetryAttemptKey, out var retryAttemptBytes))
- {
- retryAttempt = Serializer.Deserialize(retryAttemptBytes);
- }
-
- errorContext.EventData = Serializer.Deserialize(message.Value, eventType);
- errorContext.SetProperty(EventErrorHandlerBase.HeadersKey, message.Headers);
- errorContext.SetProperty(EventErrorHandlerBase.RetryAttemptKey, retryAttempt);
- });
+ await TriggerHandlersAsync(eventType, eventData);
}
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
@@ -226,7 +205,7 @@ namespace Volo.Abp.EventBus.Kafka
{
return;
}
-
+
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
await TriggerHandlersAsync(eventType, eventData, exceptions, inboxConfig);
@@ -252,11 +231,6 @@ namespace Volo.Abp.EventBus.Kafka
);
}
- public virtual async Task PublishToDeadLetterAsync(Type eventType, object eventData, Headers headers, Dictionary headersArguments)
- {
- await PublishAsync(DeadLetterTopicName, eventType, eventData, headers, headersArguments);
- }
-
private Task PublishAsync(string topicName, Type eventType, object eventData, Headers headers, Dictionary headersArguments)
{
var eventName = EventNameAttribute.GetNameOrDefault(eventType);
@@ -264,7 +238,7 @@ namespace Volo.Abp.EventBus.Kafka
return PublishAsync(topicName, eventName, body, headers, headersArguments);
}
-
+
private async Task PublishAsync(string topicName, string eventName, byte[] body, Headers headers, Dictionary headersArguments)
{
var producer = ProducerPool.Get(AbpKafkaEventBusOptions.ConnectionName);
diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaEventErrorHandler.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaEventErrorHandler.cs
deleted file mode 100644
index aee21f75a9..0000000000
--- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaEventErrorHandler.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Confluent.Kafka;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using Microsoft.Extensions.Options;
-using Volo.Abp.Data;
-using Volo.Abp.DependencyInjection;
-
-namespace Volo.Abp.EventBus.Kafka
-{
- public class KafkaEventErrorHandler : EventErrorHandlerBase, ISingletonDependency
- {
- protected ILogger Logger { get; set; }
-
- public KafkaEventErrorHandler(
- IOptions options) : base(options)
- {
- Logger = NullLogger.Instance;
- }
-
- protected override async Task RetryAsync(EventExecutionErrorContext context)
- {
- if (Options.RetryStrategyOptions.IntervalMillisecond > 0)
- {
- await Task.Delay(Options.RetryStrategyOptions.IntervalMillisecond);
- }
-
- context.TryGetRetryAttempt(out var retryAttempt);
-
- await context.EventBus.As().PublishAsync(
- context.EventType,
- context.EventData,
- context.GetProperty(HeadersKey).As(),
- new Dictionary {{RetryAttemptKey, ++retryAttempt}});
- }
-
- protected override async Task MoveToDeadLetterAsync(EventExecutionErrorContext context)
- {
- Logger.LogException(
- context.Exceptions.Count == 1 ? context.Exceptions.First() : new AggregateException(context.Exceptions),
- LogLevel.Error);
-
- await context.EventBus.As().PublishToDeadLetterAsync(
- context.EventType,
- context.EventData,
- context.GetProperty(HeadersKey).As(),
- new Dictionary {{"exceptions", context.Exceptions.Select(x => x.ToString()).ToList()}});
- }
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
index ceba890234..3188b9bcf1 100644
--- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
@@ -7,7 +7,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
-using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Guids;
@@ -26,7 +25,6 @@ namespace Volo.Abp.EventBus.RabbitMq
public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDependency
{
protected AbpRabbitMqEventBusOptions AbpRabbitMqEventBusOptions { get; }
- protected AbpEventBusOptions AbpEventBusOptions { get; }
protected IConnectionPool ConnectionPool { get; }
protected IRabbitMqSerializer Serializer { get; }
@@ -45,15 +43,12 @@ namespace Volo.Abp.EventBus.RabbitMq
IRabbitMqMessageConsumerFactory messageConsumerFactory,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
- IEventErrorHandler errorHandler,
- IOptions abpEventBusOptions,
IGuidGenerator guidGenerator,
IClock clock)
: base(
- serviceScopeFactory,
+ serviceScopeFactory,
currentTenant,
unitOfWorkManager,
- errorHandler,
distributedEventBusOptions,
guidGenerator,
clock)
@@ -61,7 +56,6 @@ namespace Volo.Abp.EventBus.RabbitMq
ConnectionPool = connectionPool;
Serializer = serializer;
MessageConsumerFactory = messageConsumerFactory;
- AbpEventBusOptions = abpEventBusOptions.Value;
AbpRabbitMqEventBusOptions = options.Value;
HandlerFactories = new ConcurrentDictionary>();
@@ -70,21 +64,17 @@ namespace Volo.Abp.EventBus.RabbitMq
public void Initialize()
{
- const string suffix = "_dead_letter";
-
Consumer = MessageConsumerFactory.Create(
new ExchangeDeclareConfiguration(
AbpRabbitMqEventBusOptions.ExchangeName,
type: "direct",
- durable: true,
- deadLetterExchangeName: AbpRabbitMqEventBusOptions.ExchangeName + suffix
+ durable: true
),
new QueueDeclareConfiguration(
AbpRabbitMqEventBusOptions.ClientName,
durable: true,
exclusive: false,
- autoDelete: false,
- AbpEventBusOptions.DeadLetterName ?? AbpRabbitMqEventBusOptions.ClientName + suffix
+ autoDelete: false
),
AbpRabbitMqEventBusOptions.ConnectionName
);
@@ -104,27 +94,15 @@ namespace Volo.Abp.EventBus.RabbitMq
}
var eventBytes = ea.Body.ToArray();
-
+
if (await AddToInboxAsync(ea.BasicProperties.MessageId, eventName, eventType, eventBytes))
{
return;
}
-
- var eventData = Serializer.Deserialize(eventBytes, eventType);
- await TriggerHandlersAsync(eventType, eventData, errorContext =>
- {
- var retryAttempt = 0;
- if (ea.BasicProperties.Headers != null &&
- ea.BasicProperties.Headers.ContainsKey(EventErrorHandlerBase.RetryAttemptKey))
- {
- retryAttempt = (int)ea.BasicProperties.Headers[EventErrorHandlerBase.RetryAttemptKey];
- }
+ var eventData = Serializer.Deserialize(eventBytes, eventType);
- errorContext.EventData = Serializer.Deserialize(eventBytes, eventType);
- errorContext.SetProperty(EventErrorHandlerBase.HeadersKey, ea.BasicProperties);
- errorContext.SetProperty(EventErrorHandlerBase.RetryAttemptKey, retryAttempt);
- });
+ await TriggerHandlersAsync(eventType, eventData);
}
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
@@ -226,7 +204,7 @@ namespace Volo.Abp.EventBus.RabbitMq
{
return;
}
-
+
var eventData = Serializer.Deserialize(incomingEvent.EventData, eventType);
var exceptions = new List();
await TriggerHandlersAsync(eventType, eventData, exceptions, inboxConfig);
@@ -235,7 +213,7 @@ namespace Volo.Abp.EventBus.RabbitMq
ThrowOriginalExceptions(eventType, exceptions);
}
}
-
+
protected override byte[] Serialize(object eventData)
{
return Serializer.Serialize(eventData);
@@ -248,7 +226,7 @@ namespace Volo.Abp.EventBus.RabbitMq
return PublishAsync(eventName, body, properties, headersArguments);
}
-
+
protected Task PublishAsync(
string eventName,
byte[] body,
@@ -274,7 +252,7 @@ namespace Volo.Abp.EventBus.RabbitMq
{
properties.MessageId = (eventId ?? GuidGenerator.Create()).ToString("N");
}
-
+
SetEventMessageHeaders(properties, headersArguments);
channel.BasicPublish(
diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqEventErrorHandler.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqEventErrorHandler.cs
deleted file mode 100644
index e8848bee72..0000000000
--- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqEventErrorHandler.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Options;
-using RabbitMQ.Client;
-using Volo.Abp.Data;
-using Volo.Abp.DependencyInjection;
-
-namespace Volo.Abp.EventBus.RabbitMq
-{
- public class RabbitMqEventErrorHandler : EventErrorHandlerBase, ISingletonDependency
- {
- public RabbitMqEventErrorHandler(
- IOptions options)
- : base(options)
- {
- }
-
- protected override async Task RetryAsync(EventExecutionErrorContext context)
- {
- if (Options.RetryStrategyOptions.IntervalMillisecond > 0)
- {
- await Task.Delay(Options.RetryStrategyOptions.IntervalMillisecond);
- }
-
- context.TryGetRetryAttempt(out var retryAttempt);
-
- await context.EventBus.As().PublishAsync(
- context.EventType,
- context.EventData,
- context.GetProperty(HeadersKey).As(),
- new Dictionary
- {
- {RetryAttemptKey, ++retryAttempt},
- {"exceptions", context.Exceptions.Select(x => x.ToString()).ToList()}
- });
- }
-
- protected override Task MoveToDeadLetterAsync(EventExecutionErrorContext context)
- {
- ThrowOriginalExceptions(context);
-
- return Task.CompletedTask;
- }
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/AbpEventBusRebusModule.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/AbpEventBusRebusModule.cs
index a13f964d3f..1ad835c122 100644
--- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/AbpEventBusRebusModule.cs
+++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/AbpEventBusRebusModule.cs
@@ -1,6 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Rebus.Handlers;
-using Rebus.Retry.Simple;
using Rebus.ServiceProvider;
using Volo.Abp.Modularity;
@@ -12,7 +11,6 @@ namespace Volo.Abp.EventBus.Rebus
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
- var abpEventBusOptions = context.Services.ExecutePreConfiguredActions();
var options = context.Services.ExecutePreConfiguredActions();;
context.Services.AddTransient(typeof(IHandleMessages<>), typeof(RebusDistributedEventHandlerAdapter<>));
@@ -24,14 +22,6 @@ namespace Volo.Abp.EventBus.Rebus
context.Services.AddRebus(configure =>
{
- if (abpEventBusOptions.RetryStrategyOptions != null)
- {
- configure.Options(b =>
- b.SimpleRetryStrategy(
- errorQueueAddress: abpEventBusOptions.DeadLetterName ?? options.InputQueueName + "_dead_letter",
- maxDeliveryAttempts: abpEventBusOptions.RetryStrategyOptions.MaxRetryAttempts));
- }
-
options.Configurer?.Invoke(configure);
return configure;
});
diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
index 1cb380679f..c0d75330cb 100644
--- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
@@ -36,7 +36,6 @@ namespace Volo.Abp.EventBus.Rebus
IBus rebus,
IOptions abpDistributedEventBusOptions,
IOptions abpEventBusRebusOptions,
- IEventErrorHandler errorHandler,
IRebusSerializer serializer,
IGuidGenerator guidGenerator,
IClock clock) :
@@ -44,7 +43,6 @@ namespace Volo.Abp.EventBus.Rebus
serviceScopeFactory,
currentTenant,
unitOfWorkManager,
- errorHandler,
abpDistributedEventBusOptions,
guidGenerator,
clock)
diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusEventErrorHandler.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusEventErrorHandler.cs
deleted file mode 100644
index 8fe6a53dbb..0000000000
--- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusEventErrorHandler.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Threading.Tasks;
-using Microsoft.Extensions.Options;
-using Volo.Abp.DependencyInjection;
-
-namespace Volo.Abp.EventBus.Rebus
-{
- ///
- /// Rebus will automatic retries and error handling: https://github.com/rebus-org/Rebus/wiki/Automatic-retries-and-error-handling
- ///
- public class RebusEventErrorHandler : EventErrorHandlerBase, ISingletonDependency
- {
- public RebusEventErrorHandler(
- IOptions options)
- : base(options)
- {
- }
-
- protected override Task RetryAsync(EventExecutionErrorContext context)
- {
- ThrowOriginalExceptions(context);
-
- return Task.CompletedTask;
- }
-
- protected override Task MoveToDeadLetterAsync(EventExecutionErrorContext context)
- {
- ThrowOriginalExceptions(context);
-
- return Task.CompletedTask;
- }
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs
index bd86f14703..3bbdf3d72b 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs
@@ -25,14 +25,6 @@ namespace Volo.Abp.EventBus
AddEventHandlers(context.Services);
}
- public override void ConfigureServices(ServiceConfigurationContext context)
- {
- Configure(options =>
- {
- context.Services.ExecutePreConfiguredActions(options);
- });
- }
-
private static void AddEventHandlers(IServiceCollection services)
{
var localHandlers = new List();
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusOptions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusOptions.cs
deleted file mode 100644
index 39631c7e18..0000000000
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusOptions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-
-namespace Volo.Abp.EventBus
-{
- public class AbpEventBusOptions
- {
- public bool EnabledErrorHandle { get; set; }
-
- public Func ErrorHandleSelector { get; set; }
-
- public string DeadLetterName { get; set; }
-
- public AbpEventBusRetryStrategyOptions RetryStrategyOptions { get; set; }
-
- public void UseRetryStrategy(Action action = null)
- {
- EnabledErrorHandle = true;
- RetryStrategyOptions = new AbpEventBusRetryStrategyOptions();
- action?.Invoke(RetryStrategyOptions);
- }
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusRetryStrategyOptions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusRetryStrategyOptions.cs
deleted file mode 100644
index 4b5b722e96..0000000000
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusRetryStrategyOptions.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Volo.Abp.EventBus
-{
- public class AbpEventBusRetryStrategyOptions
- {
- public int IntervalMillisecond { get; set; } = 3000;
-
- public int MaxRetryAttempts { get; set; } = 3;
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
index 70c5bd5533..6745327f7d 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
@@ -20,15 +20,13 @@ namespace Volo.Abp.EventBus.Distributed
IServiceScopeFactory serviceScopeFactory,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
- IEventErrorHandler errorHandler,
IOptions abpDistributedEventBusOptions,
IGuidGenerator guidGenerator,
IClock clock
) : base(
serviceScopeFactory,
currentTenant,
- unitOfWorkManager,
- errorHandler)
+ unitOfWorkManager)
{
GuidGenerator = guidGenerator;
Clock = clock;
@@ -84,7 +82,7 @@ namespace Volo.Abp.EventBus.Distributed
OutgoingEventInfo outgoingEvent,
OutboxConfig outboxConfig
);
-
+
public abstract Task ProcessFromInboxAsync(
IncomingEventInfo incomingEvent,
InboxConfig inboxConfig);
@@ -144,7 +142,7 @@ namespace Volo.Abp.EventBus.Distributed
continue;
}
}
-
+
await eventInbox.EnqueueAsync(
new IncomingEventInfo(
GuidGenerator.Create(),
@@ -163,4 +161,4 @@ namespace Volo.Abp.EventBus.Distributed
protected abstract byte[] Serialize(object eventData);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs
index 694166b1bc..46d6ecce3c 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs
@@ -22,18 +22,14 @@ namespace Volo.Abp.EventBus
protected IUnitOfWorkManager UnitOfWorkManager { get; }
- protected IEventErrorHandler ErrorHandler { get; }
-
protected EventBusBase(
IServiceScopeFactory serviceScopeFactory,
ICurrentTenant currentTenant,
- IUnitOfWorkManager unitOfWorkManager,
- IEventErrorHandler errorHandler)
+ IUnitOfWorkManager unitOfWorkManager)
{
ServiceScopeFactory = serviceScopeFactory;
CurrentTenant = currentTenant;
UnitOfWorkManager = unitOfWorkManager;
- ErrorHandler = errorHandler;
}
///
@@ -120,7 +116,7 @@ namespace Volo.Abp.EventBus
protected abstract void AddToUnitOfWork(IUnitOfWork unitOfWork, UnitOfWorkEventRecord eventRecord);
- public virtual async Task TriggerHandlersAsync(Type eventType, object eventData, Action onErrorAction = null)
+ public virtual async Task TriggerHandlersAsync(Type eventType, object eventData)
{
var exceptions = new List();
@@ -128,9 +124,7 @@ namespace Volo.Abp.EventBus
if (exceptions.Any())
{
- var context = new EventExecutionErrorContext(exceptions, eventType, this);
- onErrorAction?.Invoke(context);
- await ErrorHandler.HandleAsync(context);
+ ThrowOriginalExceptions(eventType, exceptions);
}
}
@@ -162,7 +156,7 @@ namespace Volo.Abp.EventBus
}
}
}
-
+
protected void ThrowOriginalExceptions(Type eventType, List exceptions)
{
if (exceptions.Count == 1)
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventErrorHandlerBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventErrorHandlerBase.cs
deleted file mode 100644
index ba4527fc70..0000000000
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventErrorHandlerBase.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Options;
-
-namespace Volo.Abp.EventBus
-{
- public abstract class EventErrorHandlerBase : IEventErrorHandler
- {
- public const string HeadersKey = "headers";
- public const string RetryAttemptKey = "retryAttempt";
-
- protected AbpEventBusOptions Options { get; }
-
- protected EventErrorHandlerBase(IOptions options)
- {
- Options = options.Value;
- }
-
- public virtual async Task HandleAsync(EventExecutionErrorContext context)
- {
- if (!await ShouldHandleAsync(context))
- {
- ThrowOriginalExceptions(context);
- }
-
- if (await ShouldRetryAsync(context))
- {
- await RetryAsync(context);
- return;
- }
-
- await MoveToDeadLetterAsync(context);
- }
-
- protected abstract Task RetryAsync(EventExecutionErrorContext context);
-
- protected abstract Task MoveToDeadLetterAsync(EventExecutionErrorContext context);
-
- protected virtual Task ShouldHandleAsync(EventExecutionErrorContext context)
- {
- if (!Options.EnabledErrorHandle)
- {
- return Task.FromResult(false);
- }
-
- return Task.FromResult(Options.ErrorHandleSelector == null || Options.ErrorHandleSelector.Invoke(context.EventType));
- }
-
- protected virtual Task ShouldRetryAsync(EventExecutionErrorContext context)
- {
- if (Options.RetryStrategyOptions == null)
- {
- return Task.FromResult(false);
- }
-
- if (!context.TryGetRetryAttempt(out var retryAttempt))
- {
- return Task.FromResult(false);
- }
-
- return Task.FromResult(Options.RetryStrategyOptions.MaxRetryAttempts > retryAttempt);
- }
-
- protected virtual void ThrowOriginalExceptions(EventExecutionErrorContext context)
- {
- if (context.Exceptions.Count == 1)
- {
- context.Exceptions[0].ReThrow();
- }
-
- throw new AggregateException(
- "More than one error has occurred while triggering the event: " + context.EventType,
- context.Exceptions);
- }
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventExecutionErrorContext.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventExecutionErrorContext.cs
deleted file mode 100644
index e192f61cbe..0000000000
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventExecutionErrorContext.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Volo.Abp.Data;
-using Volo.Abp.ObjectExtending;
-
-namespace Volo.Abp.EventBus
-{
- public class EventExecutionErrorContext : ExtensibleObject
- {
- public IReadOnlyList Exceptions { get; }
-
- public object EventData { get; set; }
-
- public Type EventType { get; }
-
- public IEventBus EventBus { get; }
-
- public EventExecutionErrorContext(List exceptions, Type eventType, IEventBus eventBus)
- {
- Exceptions = exceptions;
- EventType = eventType;
- EventBus = eventBus;
- }
-
- public bool TryGetRetryAttempt(out int retryAttempt)
- {
- retryAttempt = 0;
- if (!this.HasProperty(EventErrorHandlerBase.RetryAttemptKey))
- {
- return false;
- }
-
- retryAttempt = this.GetProperty(EventErrorHandlerBase.RetryAttemptKey);
- return true;
-
- }
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventErrorHandler.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventErrorHandler.cs
deleted file mode 100644
index f1b4a40f15..0000000000
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventErrorHandler.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Volo.Abp.EventBus
-{
- public interface IEventErrorHandler
- {
- Task HandleAsync(EventExecutionErrorContext context);
- }
-}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs
index 77bf5b43bd..4da09bf608 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs
@@ -7,11 +7,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
-using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
-using Volo.Abp.Json;
using Volo.Abp.Uow;
namespace Volo.Abp.EventBus.Local
@@ -35,9 +33,8 @@ namespace Volo.Abp.EventBus.Local
IOptions options,
IServiceScopeFactory serviceScopeFactory,
ICurrentTenant currentTenant,
- IUnitOfWorkManager unitOfWorkManager,
- IEventErrorHandler errorHandler)
- : base(serviceScopeFactory, currentTenant, unitOfWorkManager, errorHandler)
+ IUnitOfWorkManager unitOfWorkManager)
+ : base(serviceScopeFactory, currentTenant, unitOfWorkManager)
{
Options = options.Value;
Logger = NullLogger.Instance;
@@ -134,11 +131,7 @@ namespace Volo.Abp.EventBus.Local
public virtual async Task PublishAsync(LocalEventMessage localEventMessage)
{
- await TriggerHandlersAsync(localEventMessage.EventType, localEventMessage.EventData, errorContext =>
- {
- errorContext.EventData = localEventMessage.EventData;
- errorContext.SetProperty(nameof(LocalEventMessage.MessageId), localEventMessage.MessageId);
- });
+ await TriggerHandlersAsync(localEventMessage.EventType, localEventMessage.EventData);
}
protected override IEnumerable GetHandlerFactories(Type eventType)
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventErrorHandler.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventErrorHandler.cs
deleted file mode 100644
index c08bca019f..0000000000
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventErrorHandler.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Options;
-using Volo.Abp.Data;
-using Volo.Abp.DependencyInjection;
-
-namespace Volo.Abp.EventBus.Local
-{
- [ExposeServices(typeof(LocalEventErrorHandler), typeof(IEventErrorHandler))]
- public class LocalEventErrorHandler : EventErrorHandlerBase, ISingletonDependency
- {
- protected Dictionary RetryTracking { get; }
-
- public LocalEventErrorHandler(
- IOptions options)
- : base(options)
- {
- RetryTracking = new Dictionary();
- }
-
- protected override async Task RetryAsync(EventExecutionErrorContext context)
- {
- if (Options.RetryStrategyOptions.IntervalMillisecond > 0)
- {
- await Task.Delay(Options.RetryStrategyOptions.IntervalMillisecond);
- }
-
- var messageId = context.GetProperty(nameof(LocalEventMessage.MessageId));
-
- context.TryGetRetryAttempt(out var retryAttempt);
- RetryTracking[messageId] = ++retryAttempt;
-
- await context.EventBus.As().PublishAsync(new LocalEventMessage(messageId, context.EventData, context.EventType));
-
- RetryTracking.Remove(messageId);
- }
-
- protected override Task MoveToDeadLetterAsync(EventExecutionErrorContext context)
- {
- ThrowOriginalExceptions(context);
-
- return Task.CompletedTask;
- }
-
- protected override async Task ShouldRetryAsync(EventExecutionErrorContext context)
- {
- var messageId = context.GetProperty(nameof(LocalEventMessage.MessageId));
- context.SetProperty(RetryAttemptKey, RetryTracking.GetOrDefault(messageId));
-
- if (await base.ShouldRetryAsync(context))
- {
- return true;
- }
-
- RetryTracking.Remove(messageId);
- return false;
- }
- }
-}
diff --git a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/IKafkaMessageConsumerFactory.cs b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/IKafkaMessageConsumerFactory.cs
index 96ec753dc2..2b01b5a935 100644
--- a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/IKafkaMessageConsumerFactory.cs
+++ b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/IKafkaMessageConsumerFactory.cs
@@ -8,13 +8,11 @@
/// not disposed until end of the application.
///
///
- ///
///
///
///
IKafkaMessageConsumer Create(
string topicName,
- string deadLetterTopicName,
string groupId,
string connectionName = null);
}
diff --git a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs
index d1bad00533..afed026402 100644
--- a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs
+++ b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs
@@ -39,8 +39,6 @@ namespace Volo.Abp.Kafka
protected string TopicName { get; private set; }
- protected string DeadLetterTopicName { get; private set; }
-
public KafkaMessageConsumer(
IConsumerPool consumerPool,
IExceptionNotifier exceptionNotifier,
@@ -64,15 +62,12 @@ namespace Volo.Abp.Kafka
public virtual void Initialize(
[NotNull] string topicName,
- [NotNull] string deadLetterTopicName,
[NotNull] string groupId,
string connectionName = null)
{
Check.NotNull(topicName, nameof(topicName));
- Check.NotNull(deadLetterTopicName, nameof(deadLetterTopicName));
Check.NotNull(groupId, nameof(groupId));
TopicName = topicName;
- DeadLetterTopicName = deadLetterTopicName;
ConnectionName = connectionName ?? KafkaConnections.DefaultConnectionName;
GroupId = groupId;
Timer.Start();
@@ -94,30 +89,18 @@ namespace Volo.Abp.Kafka
{
using (var adminClient = new AdminClientBuilder(Options.Connections.GetOrDefault(ConnectionName)).Build())
{
- var topics = new List
+ var topic = new TopicSpecification
{
- new()
- {
- Name = TopicName,
- NumPartitions = 1,
- ReplicationFactor = 1
- },
- new()
- {
- Name = DeadLetterTopicName,
- NumPartitions = 1,
- ReplicationFactor = 1
- }
+ Name = TopicName,
+ NumPartitions = 1,
+ ReplicationFactor = 1
};
- topics.ForEach(topic =>
- {
- Options.ConfigureTopic?.Invoke(topic);
- });
+ Options.ConfigureTopic?.Invoke(topic);
try
{
- await adminClient.CreateTopicsAsync(topics);
+ await adminClient.CreateTopicsAsync(new[] {topic});
}
catch (CreateTopicsException e)
{
diff --git a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumerFactory.cs b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumerFactory.cs
index 4a22fd04f6..9d199b15f9 100644
--- a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumerFactory.cs
+++ b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumerFactory.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
@@ -16,12 +15,11 @@ namespace Volo.Abp.Kafka
public IKafkaMessageConsumer Create(
string topicName,
- string deadLetterTopicName,
string groupId,
string connectionName = null)
{
var consumer = ServiceScope.ServiceProvider.GetRequiredService();
- consumer.Initialize(topicName, deadLetterTopicName, groupId, connectionName);
+ consumer.Initialize(topicName, groupId, connectionName);
return consumer;
}
diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs
index b9e762abbe..8ea919484a 100644
--- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs
+++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs
@@ -6,8 +6,6 @@ namespace Volo.Abp.RabbitMQ
{
public string ExchangeName { get; }
- public string DeadLetterExchangeName { get; set; }
-
public string Type { get; }
public bool Durable { get; set; }
@@ -20,11 +18,9 @@ namespace Volo.Abp.RabbitMQ
string exchangeName,
string type,
bool durable = false,
- bool autoDelete = false,
- string deadLetterExchangeName = null)
+ bool autoDelete = false)
{
ExchangeName = exchangeName;
- DeadLetterExchangeName = deadLetterExchangeName;
Type = type;
Durable = durable;
AutoDelete = autoDelete;
diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs
index b84f08ec42..211dc3d7b2 100644
--- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs
+++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs
@@ -8,8 +8,6 @@ namespace Volo.Abp.RabbitMQ
{
[NotNull] public string QueueName { get; }
- public string DeadLetterQueueName { get; set; }
-
public bool Durable { get; set; }
public bool Exclusive { get; set; }
@@ -22,11 +20,9 @@ namespace Volo.Abp.RabbitMQ
[NotNull] string queueName,
bool durable = true,
bool exclusive = false,
- bool autoDelete = false,
- string deadLetterQueueName = null)
+ bool autoDelete = false)
{
QueueName = queueName;
- DeadLetterQueueName = deadLetterQueueName;
Durable = durable;
Exclusive = exclusive;
AutoDelete = autoDelete;
diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
index 671445e00d..a0c1251c6c 100644
--- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
+++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
@@ -157,29 +157,7 @@ namespace Volo.Abp.RabbitMQ
arguments: Exchange.Arguments
);
- if (!Exchange.DeadLetterExchangeName.IsNullOrWhiteSpace() &&
- !Queue.DeadLetterQueueName.IsNullOrWhiteSpace())
- {
- Channel.ExchangeDeclare(
- Exchange.DeadLetterExchangeName,
- Exchange.Type,
- Exchange.Durable,
- Exchange.AutoDelete
- );
-
- Channel.QueueDeclare(
- Queue.DeadLetterQueueName,
- Queue.Durable,
- Queue.Exclusive,
- Queue.AutoDelete);
-
- Queue.Arguments["x-dead-letter-exchange"] = Exchange.DeadLetterExchangeName;
- Queue.Arguments["x-dead-letter-routing-key"] = Queue.DeadLetterQueueName;
-
- Channel.QueueBind(Queue.DeadLetterQueueName, Exchange.DeadLetterExchangeName, Queue.DeadLetterQueueName);
- }
-
- var result = Channel.QueueDeclare(
+ Channel.QueueDeclare(
queue: Queue.QueueName,
durable: Queue.Durable,
exclusive: Queue.Exclusive,
@@ -202,11 +180,8 @@ namespace Volo.Abp.RabbitMQ
operationInterruptedException.ShutdownReason.ReplyCode == 406 &&
operationInterruptedException.Message.Contains("arg 'x-dead-letter-exchange'"))
{
- Exchange.DeadLetterExchangeName = null;
- Queue.DeadLetterQueueName = null;
- Queue.Arguments.Remove("x-dead-letter-exchange");
- Queue.Arguments.Remove("x-dead-letter-routing-key");
- Logger.LogWarning("Unable to bind the dead letter queue to an existing queue. You can delete the queue or add policy. See: https://www.rabbitmq.com/parameters.html");
+ Logger.LogException(ex, LogLevel.Warning);
+ await ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning);
}
Logger.LogException(ex, LogLevel.Warning);
@@ -229,8 +204,13 @@ namespace Volo.Abp.RabbitMQ
{
try
{
- Channel.BasicReject(basicDeliverEventArgs.DeliveryTag, false);
+ Channel.BasicNack(
+ basicDeliverEventArgs.DeliveryTag,
+ multiple: false,
+ requeue: true
+ );
}
+ // ReSharper disable once EmptyGeneralCatchClause
catch { }
Logger.LogException(ex);
diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/EventBusTestModule.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/EventBusTestModule.cs
index f260fecbea..9a4258c621 100644
--- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/EventBusTestModule.cs
+++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/EventBusTestModule.cs
@@ -5,17 +5,5 @@ namespace Volo.Abp.EventBus
[DependsOn(typeof(AbpEventBusModule))]
public class EventBusTestModule : AbpModule
{
- public override void PreConfigureServices(ServiceConfigurationContext context)
- {
- PreConfigure(options =>
- {
- options.UseRetryStrategy(retryStrategyOptions =>
- {
- retryStrategyOptions.IntervalMillisecond = 0;
- });
-
- options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
- });
- }
}
}
diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Exception_Handler_Tests.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Exception_Handler_Tests.cs
deleted file mode 100644
index 3ed0ff19f9..0000000000
--- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Exception_Handler_Tests.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Shouldly;
-using Xunit;
-
-namespace Volo.Abp.EventBus.Local
-{
- public class EventBus_Exception_Handler_Tests : EventBusTestBase
- {
- [Fact]
- public async Task Should_Not_Handle_Exception()
- {
- var retryAttempt = 0;
- LocalEventBus.Subscribe(eventData =>
- {
- retryAttempt++;
- throw new Exception("This exception is intentionally thrown!");
- });
-
- var appException = await Assert.ThrowsAsync(async () =>
- {
- await LocalEventBus.PublishAsync(new MySimpleEventData(1));
- });
-
- retryAttempt.ShouldBe(1);
- appException.Message.ShouldBe("This exception is intentionally thrown!");
- }
-
- [Fact]
- public async Task Should_Handle_Exception()
- {
- var retryAttempt = 0;
- LocalEventBus.Subscribe(eventData =>
- {
- eventData.Value.ShouldBe(0);
- retryAttempt++;
- if (retryAttempt < 2)
- {
- throw new Exception("This exception is intentionally thrown!");
- }
-
- return Task.CompletedTask;
-
- });
-
- await LocalEventBus.PublishAsync(new MyExceptionHandleEventData(0));
- retryAttempt.ShouldBe(2);
- }
-
- [Fact]
- public async Task Should_Throw_Exception_After_Error_Handle()
- {
- var retryAttempt = 0;
- LocalEventBus.Subscribe(eventData =>
- {
- eventData.Value.ShouldBe(0);
-
- retryAttempt++;
-
- throw new Exception("This exception is intentionally thrown!");
- });
-
- var appException = await Assert.ThrowsAsync(async () =>
- {
- await LocalEventBus.PublishAsync(new MyExceptionHandleEventData(0));
- });
-
- retryAttempt.ShouldBe(4);
- appException.Message.ShouldBe("This exception is intentionally thrown!");
- }
- }
-}
diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/MyExceptionHandleEventData.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/MyExceptionHandleEventData.cs
deleted file mode 100644
index f490d58211..0000000000
--- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/MyExceptionHandleEventData.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Volo.Abp.EventBus
-{
- public class MyExceptionHandleEventData
- {
- public int Value { get; set; }
-
- public MyExceptionHandleEventData(int value)
- {
- Value = value;
- }
- }
-}
diff --git a/modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs b/modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs
index d1f22587e8..13910ac6ab 100644
--- a/modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs
+++ b/modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs
@@ -8,7 +8,7 @@ namespace Volo.Abp.Account
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Area("account")]
[Route("api/account")]
- public class AccountController : AbpController, IAccountAppService
+ public class AccountController : AbpControllerBase, IAccountAppService
{
protected IAccountAppService AccountAppService { get; }
diff --git a/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs b/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
index ec9f26179d..dd8a853350 100644
--- a/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
+++ b/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
@@ -22,7 +22,7 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
[ControllerName("Login")]
[Area("account")]
[Route("api/account")]
- public class AccountController : AbpController
+ public class AccountController : AbpControllerBase
{
protected SignInManager SignInManager { get; }
protected IdentityUserManager UserManager { get; }
diff --git a/modules/blogging/src/Volo.Blogging.Admin.HttpApi/Volo/Blogging/Admin/BlogManagementController.cs b/modules/blogging/src/Volo.Blogging.Admin.HttpApi/Volo/Blogging/Admin/BlogManagementController.cs
index ce6457dcc7..4ee705551e 100644
--- a/modules/blogging/src/Volo.Blogging.Admin.HttpApi/Volo/Blogging/Admin/BlogManagementController.cs
+++ b/modules/blogging/src/Volo.Blogging.Admin.HttpApi/Volo/Blogging/Admin/BlogManagementController.cs
@@ -13,7 +13,7 @@ namespace Volo.Blogging.Admin
[RemoteService(Name = BloggingAdminRemoteServiceConsts.RemoteServiceName)]
[Area("bloggingAdmin")]
[Route("api/blogging/blogs/admin")]
- public class BlogManagementController : AbpController, IBlogManagementAppService
+ public class BlogManagementController : AbpControllerBase, IBlogManagementAppService
{
private readonly IBlogManagementAppService _blogManagementAppService;
diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs
index 12bedc3e6c..898d3fe09b 100644
--- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs
+++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs
@@ -10,7 +10,7 @@ namespace Volo.Blogging
[RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)]
[Area("blogging")]
[Route("api/blogging/files")]
- public class BlogFilesController : AbpController, IFileAppService
+ public class BlogFilesController : AbpControllerBase, IFileAppService
{
private readonly IFileAppService _fileAppService;
diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs
index 9ef141b3de..af46d0784a 100644
--- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs
+++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs
@@ -12,7 +12,7 @@ namespace Volo.Blogging
[RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)]
[Area("blogging")]
[Route("api/blogging/blogs")]
- public class BlogsController : AbpController, IBlogAppService
+ public class BlogsController : AbpControllerBase, IBlogAppService
{
private readonly IBlogAppService _blogAppService;
diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs
index caea1cfa2f..73d6a115f4 100644
--- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs
+++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs
@@ -12,7 +12,7 @@ namespace Volo.Blogging
[RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)]
[Area("blogging")]
[Route("api/blogging/comments")]
- public class CommentsController : AbpController, ICommentAppService
+ public class CommentsController : AbpControllerBase, ICommentAppService
{
private readonly ICommentAppService _commentAppService;
diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs
index f3d67af815..66f8f7afab 100644
--- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs
+++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs
@@ -11,7 +11,7 @@ namespace Volo.Blogging
[RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)]
[Area("blogging")]
[Route("api/blogging/posts")]
- public class PostsController : AbpController, IPostAppService
+ public class PostsController : AbpControllerBase, IPostAppService
{
private readonly IPostAppService _postAppService;
diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs
index 4c2c34db44..262e5ac801 100644
--- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs
+++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs
@@ -12,7 +12,7 @@ namespace Volo.Blogging
[RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)]
[Area("blogging")]
[Route("api/blogging/tags")]
- public class TagsController : AbpController, ITagAppService
+ public class TagsController : AbpControllerBase, ITagAppService
{
private readonly ITagAppService _tagAppService;
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/CmsKitAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/CmsKitAdminController.cs
index f4303c0245..fc89a0c63b 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/CmsKitAdminController.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/CmsKitAdminController.cs
@@ -3,7 +3,7 @@ using Volo.CmsKit.Localization;
namespace Volo.CmsKit.Admin
{
- public abstract class CmsKitAdminController : AbpController
+ public abstract class CmsKitAdminController : AbpControllerBase
{
protected CmsKitAdminController()
{
diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitControllerBase.cs b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitControllerBase.cs
index 70a68c7611..4ac5d5423b 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitControllerBase.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitControllerBase.cs
@@ -3,7 +3,7 @@ using Volo.CmsKit.Localization;
namespace Volo.CmsKit
{
- public abstract class CmsKitControllerBase : AbpController
+ public abstract class CmsKitControllerBase : AbpControllerBase
{
protected CmsKitControllerBase()
{
diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
index 88b1d99d1d..f08c8e8f71 100644
--- a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
+++ b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
@@ -13,7 +13,7 @@ namespace Volo.Docs.Admin
[Area("docs-admin")]
[ControllerName("DocumentsAdmin")]
[Route("api/docs/admin/documents")]
- public class DocumentsAdminController : AbpController, IDocumentAdminAppService
+ public class DocumentsAdminController : AbpControllerBase, IDocumentAdminAppService
{
private readonly IDocumentAdminAppService _documentAdminAppService;
diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/ProjectsAdminController.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/ProjectsAdminController.cs
index 2e09342175..968e60adb7 100644
--- a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/ProjectsAdminController.cs
+++ b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/ProjectsAdminController.cs
@@ -12,7 +12,7 @@ namespace Volo.Docs.Admin
[Area("docs-admin")]
[ControllerName("ProjectsAdmin")]
[Route("api/docs/admin/projects")]
- public class ProjectsAdminController : AbpController, IProjectAdminAppService
+ public class ProjectsAdminController : AbpControllerBase, IProjectAdminAppService
{
private readonly IProjectAdminAppService _projectAppService;
diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs
index 602cc970dd..24d9a51491 100644
--- a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs
+++ b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs
@@ -11,7 +11,7 @@ namespace Volo.Docs.Projects
[Area("docs")]
[ControllerName("Project")]
[Route("api/docs/projects")]
- public class DocsProjectController : AbpController, IProjectAppService
+ public class DocsProjectController : AbpControllerBase, IProjectAppService
{
protected IProjectAppService ProjectAppService { get; }
diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs
index c7dff4d8a3..4a70fefdd9 100644
--- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs
+++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.FeatureManagement
[RemoteService(Name = FeatureManagementRemoteServiceConsts.RemoteServiceName)]
[Area("featureManagement")]
[Route("api/feature-management/features")]
- public class FeaturesController : AbpController, IFeatureAppService
+ public class FeaturesController : AbpControllerBase, IFeatureAppService
{
protected IFeatureAppService FeatureAppService { get; }
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityRoleController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityRoleController.cs
index 150256badd..38d5f68a41 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityRoleController.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityRoleController.cs
@@ -10,7 +10,7 @@ namespace Volo.Abp.Identity
[Area("identity")]
[ControllerName("Role")]
[Route("api/identity/roles")]
- public class IdentityRoleController : AbpController, IIdentityRoleAppService
+ public class IdentityRoleController : AbpControllerBase, IIdentityRoleAppService
{
protected IIdentityRoleAppService RoleAppService { get; }
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs
index c02ea23e9f..7de9de2826 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs
@@ -10,7 +10,7 @@ namespace Volo.Abp.Identity
[Area("identity")]
[ControllerName("User")]
[Route("api/identity/users")]
- public class IdentityUserController : AbpController, IIdentityUserAppService
+ public class IdentityUserController : AbpControllerBase, IIdentityUserAppService
{
protected IIdentityUserAppService UserAppService { get; }
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserLookupController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserLookupController.cs
index 75fc20a520..d0676ffb7d 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserLookupController.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserLookupController.cs
@@ -11,7 +11,7 @@ namespace Volo.Abp.Identity
[Area("identity")]
[ControllerName("UserLookup")]
[Route("api/identity/users/lookup")]
- public class IdentityUserLookupController : AbpController, IIdentityUserLookupAppService
+ public class IdentityUserLookupController : AbpControllerBase, IIdentityUserLookupAppService
{
protected IIdentityUserLookupAppService LookupAppService { get; }
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs
index 91b1bc8325..f16c780d93 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs
@@ -8,7 +8,7 @@ namespace Volo.Abp.Identity
[Area("identity")]
[ControllerName("Profile")]
[Route("/api/identity/my-profile")]
- public class ProfileController : AbpController, IProfileAppService
+ public class ProfileController : AbpControllerBase, IProfileAppService
{
protected IProfileAppService ProfileAppService { get; }
diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs
index bb9db51f98..a9a6096053 100644
--- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs
+++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.PermissionManagement
[RemoteService(Name = PermissionManagementRemoteServiceConsts.RemoteServiceName)]
[Area("permissionManagement")]
[Route("api/permission-management/permissions")]
- public class PermissionsController : AbpController, IPermissionAppService
+ public class PermissionsController : AbpControllerBase, IPermissionAppService
{
protected IPermissionAppService PermissionAppService { get; }
diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo/Abp/SettingManagement/EmailSettingsController.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo/Abp/SettingManagement/EmailSettingsController.cs
index 7ddb284c64..5e01f5b984 100644
--- a/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo/Abp/SettingManagement/EmailSettingsController.cs
+++ b/modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi/Volo/Abp/SettingManagement/EmailSettingsController.cs
@@ -7,7 +7,7 @@ namespace Volo.Abp.SettingManagement
[RemoteService(Name = SettingManagementRemoteServiceConsts.RemoteServiceName)]
[Area("settingManagement")]
[Route("api/setting-management/emailing")]
- public class EmailSettingsController : AbpController, IEmailSettingsAppService
+ public class EmailSettingsController : AbpControllerBase, IEmailSettingsAppService
{
private readonly IEmailSettingsAppService _emailSettingsAppService;
diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs
index 317e7e62d0..9c5062f96e 100644
--- a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs
+++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs
@@ -10,7 +10,7 @@ namespace Volo.Abp.TenantManagement
[RemoteService(Name = TenantManagementRemoteServiceConsts.RemoteServiceName)]
[Area("multi-tenancy")]
[Route("api/multi-tenancy/tenants")]
- public class TenantController : AbpController, ITenantAppService //TODO: Throws exception on validation if we inherit from Controller
+ public class TenantController : AbpControllerBase, ITenantAppService //TODO: Throws exception on validation if we inherit from Controller
{
protected ITenantAppService TenantAppService { get; }
diff --git a/npm/ng-packs/packages/components/chart.js/src/chart.component.ts b/npm/ng-packs/packages/components/chart.js/src/chart.component.ts
index 670ba01f42..2ac9e1d057 100644
--- a/npm/ng-packs/packages/components/chart.js/src/chart.component.ts
+++ b/npm/ng-packs/packages/components/chart.js/src/chart.component.ts
@@ -88,7 +88,7 @@ export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges {
}
}
- initChart = () => {
+ private initChart = () => {
const opts = this.options || {};
opts.responsive = this.responsive;
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html
index 4544d1022a..83314c22f2 100644
--- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html
+++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html
@@ -25,14 +25,24 @@
>
-
+
+
+
+
+
+
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts
index 1c1757a410..8e1d2752be 100644
--- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts
+++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts
@@ -1,4 +1,5 @@
import {
+ ABP,
ConfigStateService,
getShortDateFormat,
getShortDateShortTimeFormat,
@@ -29,7 +30,8 @@ import { EntityActionList } from '../../models/entity-actions';
import { EntityProp, EntityPropList } from '../../models/entity-props';
import { PropData } from '../../models/props';
import { ExtensionsService } from '../../services/extensions.service';
-import { EXTENSIONS_IDENTIFIER } from '../../tokens/extensions.token';
+import { EXTENSIONS_IDENTIFIER, PROP_DATA_STREAM } from '../../tokens/extensions.token';
+
const DEFAULT_ACTIONS_COLUMN_WIDTH = 150;
@Component({
@@ -71,7 +73,7 @@ export class ExtensibleTableComponent implements OnChanges {
constructor(
@Inject(LOCALE_ID) private locale: string,
private config: ConfigStateService,
- injector: Injector,
+ private injector: Injector,
) {
this.getInjected = injector.get.bind(injector);
const extensions = injector.get(ExtensionsService);
@@ -106,6 +108,12 @@ export class ExtensibleTableComponent implements OnChanges {
: '
';
}
+ private getEnum(rowValue: any, list: Array>) {
+ if (!list) return rowValue;
+ const { key } = list.find(({ value }) => value === rowValue);
+ return key;
+ }
+
getContent(prop: EntityProp, data: PropData): Observable {
return prop.valueResolver(data).pipe(
map(value => {
@@ -118,6 +126,8 @@ export class ExtensibleTableComponent implements OnChanges {
return this.getDate(value, getShortTimeFormat(this.config));
case ePropType.DateTime:
return this.getDate(value, getShortDateShortTimeFormat(this.config));
+ case ePropType.Enum:
+ return this.getEnum(value, prop.enumList);
default:
return value;
// More types can be handled in the future
@@ -132,10 +142,26 @@ export class ExtensibleTableComponent implements OnChanges {
this.data = data.currentValue.map((record, index) => {
this.propList.forEach(prop => {
const propData = { getInjected: this.getInjected, record, index } as any;
- record[`_${prop.value.name}`] = {
+ const value = this.getContent(prop.value, propData);
+
+ const propKey = `_${prop.value.name}`;
+ record[propKey] = {
visible: prop.value.visible(propData),
- value: this.getContent(prop.value, propData),
+ value,
};
+ if (prop.value.component) {
+ const injector = Injector.create(
+ [
+ {
+ provide: PROP_DATA_STREAM,
+ useValue: value,
+ },
+ ],
+ this.injector,
+ );
+ record[propKey].injector = injector;
+ record[propKey].component = prop.value.component;
+ }
});
return record;
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-props.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-props.ts
index 1342480cd8..fad8c29ade 100644
--- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-props.ts
+++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-props.ts
@@ -1,6 +1,7 @@
import { Type } from '@angular/core';
import { Observable, of } from 'rxjs';
import { O } from 'ts-toolbelt';
+import { ABP } from '@abp/ng.core';
import { ActionCallback } from './actions';
import {
Prop,
@@ -27,6 +28,8 @@ export class EntityProp extends Prop {
readonly sortable: boolean;
readonly valueResolver: PropCallback>;
readonly action: ActionCallback;
+ readonly component: Type;
+ readonly enumList: Array>;
constructor(options: EntityPropOptions) {
super(
@@ -42,6 +45,8 @@ export class EntityProp extends Prop {
this.sortable = options.sortable || false;
this.valueResolver = options.valueResolver || (data => of(data.record[this.name]));
this.action = options.action;
+ this.component = options.component;
+ this.enumList = options.enumList;
}
static create(options: EntityPropOptions) {
@@ -63,6 +68,8 @@ export type EntityPropOptions = O.Optional<
| 'sortable'
| 'valueResolver'
| 'action'
+ | 'component'
+ | 'enumList'
>;
export type EntityPropDefaults = Record[]>;
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/tokens/extensions.token.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/tokens/extensions.token.ts
index ba504756aa..f0343169c1 100644
--- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/tokens/extensions.token.ts
+++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/tokens/extensions.token.ts
@@ -1,6 +1,7 @@
import { InjectionToken } from '@angular/core';
import { ActionCallback, ReadonlyActionData as ActionData } from '../models/actions';
import { ExtensionsService } from '../services/extensions.service';
+import { Observable } from 'rxjs';
export const EXTENSIONS_IDENTIFIER = new InjectionToken('EXTENSIONS_IDENTIFIER');
export type ActionKeys = Extract<'entityActions' | 'toolbarActions', keyof ExtensionsService>;
@@ -11,3 +12,4 @@ export const EXTENSIONS_ACTION_DATA = new InjectionToken('EXTENSIONS
export const EXTENSIONS_ACTION_CALLBACK = new InjectionToken>(
'EXTENSIONS_ACTION_DATA',
);
+export const PROP_DATA_STREAM = new InjectionToken>('PROP_DATA_STREAM');
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.html
new file mode 100644
index 0000000000..b4c45b7a17
--- /dev/null
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.html
@@ -0,0 +1,23 @@
+
+ -
+
+
+ -
+
+
+
+
+
+ {{ item.name | abpLocalization }}
+
+
+
+ {{ item.name | abpLocalization }}
+
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.ts
new file mode 100644
index 0000000000..1bba2e9ece
--- /dev/null
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.ts
@@ -0,0 +1,9 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector: 'abp-breadcrumb-items',
+ templateUrl: './breadcrumb-items.component.html',
+})
+export class BreadcrumbItemsComponent {
+ @Input() items = [];
+}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html
index da17512ea1..b23fdc598e 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html
@@ -1,13 +1 @@
-
- -
-
-
- -
- {{ segment.name | abpLocalization }}
-
-
+
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
index 69a5c81af2..68ac0212ff 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
@@ -1,11 +1,4 @@
-import {
- ABP,
- getRoutePath,
- RouterEvents,
- RoutesService,
- SubscriptionService,
- TreeNode,
-} from '@abp/ng.core';
+import { ABP, getRoutePath, RouterEvents, RoutesService, SubscriptionService, TreeNode } from '@abp/ng.core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { map, startWith } from 'rxjs/operators';
@@ -41,7 +34,7 @@ export class BreadcrumbComponent implements OnInit {
while (node.parent) {
node = node.parent;
- const { parent, children, isLeaf, ...segment } = node;
+ const { parent, children, isLeaf, path, ...segment } = node;
if (!isAdministration(segment)) this.segments.unshift(segment);
}
@@ -52,6 +45,6 @@ export class BreadcrumbComponent implements OnInit {
}
}
-function isAdministration(route: ABP.Route) {
+function isAdministration(route: Pick) {
return route.name === eThemeSharedRouteNames.Administration;
}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
index 8575e834ed..0dcbb525db 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
@@ -11,6 +11,7 @@ import {
} from '@ngx-validate/core';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';
+import { BreadcrumbItemsComponent } from './components/breadcrumb-items/breadcrumb-items.component';
import { ButtonComponent } from './components/button/button.component';
import { ConfirmationComponent } from './components/confirmation/confirmation.component';
import { HttpErrorWrapperComponent } from './components/http-error-wrapper/http-error-wrapper.component';
@@ -36,6 +37,7 @@ import { DateParserFormatter } from './utils/date-parser-formatter';
const declarationsWithExports = [
BreadcrumbComponent,
+ BreadcrumbItemsComponent,
ButtonComponent,
ConfirmationComponent,
LoaderBarComponent,
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs
index 7fff0ecbc5..346f27f7a3 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs
@@ -5,7 +5,7 @@ namespace MyCompanyName.MyProjectName.Controllers
{
/* Inherit your controllers from this class.
*/
- public abstract class MyProjectNameController : AbpController
+ public abstract class MyProjectNameController : AbpControllerBase
{
protected MyProjectNameController()
{
diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs
index 1dd9a6c8b2..699cc3df56 100644
--- a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs
+++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs
@@ -3,7 +3,7 @@ using Volo.Abp.AspNetCore.Mvc;
namespace MyCompanyName.MyProjectName
{
- public abstract class MyProjectNameController : AbpController
+ public abstract class MyProjectNameController : AbpControllerBase
{
protected MyProjectNameController()
{