diff --git a/Source/Euonia.Bus.Abstract/Exceptions/MessageDeliverException.cs b/Source/Euonia.Bus.Abstract/Exceptions/MessageDeliverException.cs
new file mode 100644
index 0000000..e3d3707
--- /dev/null
+++ b/Source/Euonia.Bus.Abstract/Exceptions/MessageDeliverException.cs
@@ -0,0 +1,34 @@
+namespace Nerosoft.Euonia.Bus;
+
+///
+/// Represents errors that occur during message deliver.
+///
+public class MessageDeliverException : Exception
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MessageDeliverException()
+ : base("Error occurred during message deliver.")
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ public MessageDeliverException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ public MessageDeliverException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+}
diff --git a/Source/Euonia.Bus.Abstract/Exceptions/MessageTypeException.cs b/Source/Euonia.Bus.Abstract/Exceptions/MessageTypeException.cs
new file mode 100644
index 0000000..0270b44
--- /dev/null
+++ b/Source/Euonia.Bus.Abstract/Exceptions/MessageTypeException.cs
@@ -0,0 +1,34 @@
+namespace Nerosoft.Euonia.Bus;
+
+///
+/// Represents errors that occur when the message type is invalid.
+///
+public class MessageTypeException : Exception
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MessageTypeException()
+ : base("The message type is invalid.")
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ public MessageTypeException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ public MessageTypeException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+}
diff --git a/Source/Euonia.Bus.InMemory/InMemoryRecipientRegistrar.cs b/Source/Euonia.Bus.InMemory/InMemoryRecipientRegistrar.cs
index c77b1bf..049f058 100644
--- a/Source/Euonia.Bus.InMemory/InMemoryRecipientRegistrar.cs
+++ b/Source/Euonia.Bus.InMemory/InMemoryRecipientRegistrar.cs
@@ -46,7 +46,7 @@ public async Task RegisterAsync(IEnumerable registrations,
}
else
{
- throw new InvalidOperationException();
+ throw new MessageTypeException("The message type is neither a queue nor a topic.");
}
}
diff --git a/Source/Euonia.Bus.InMemory/Messenger/StrongReferenceMessenger.cs b/Source/Euonia.Bus.InMemory/Messenger/StrongReferenceMessenger.cs
index c3e7ddd..52679d5 100644
--- a/Source/Euonia.Bus.InMemory/Messenger/StrongReferenceMessenger.cs
+++ b/Source/Euonia.Bus.InMemory/Messenger/StrongReferenceMessenger.cs
@@ -606,7 +606,7 @@ public TMessage Send(TMessage message, TToken token)
/// The token indicating what channel to use.
/// The message that was sent (ie. ).
/// Thrown if or are .
- public TMessage UnsafeSend(TMessage message, TToken token)
+ internal TMessage UnsafeSend(TMessage message, TToken token)
where TMessage : class
where TToken : IEquatable
{
@@ -624,7 +624,7 @@ public TMessage UnsafeSend(TMessage message, TToken token)
// Check whether there are any registered recipients
if (!TryGetMapping(out var mapping))
{
- throw new InvalidOperationException("No recipients registered for the input message type.");
+ throw new MessageDeliverException("No recipients registered for the input message type.");
}
// Check the number of remaining handlers, see below
@@ -632,7 +632,7 @@ public TMessage UnsafeSend(TMessage message, TToken token)
if (totalHandlersCount == 0)
{
- throw new InvalidOperationException("No recipients registered for the input message type.");
+ throw new MessageDeliverException("No recipients registered for the input message type.");
}
pairs = rentedArray = ArrayPool.Shared.Rent(2 * totalHandlersCount);
@@ -670,7 +670,7 @@ public TMessage UnsafeSend(TMessage message, TToken token)
if (totalHandlersCount == 0)
{
- throw new InvalidOperationException("No recipients registered for the input message type.");
+ throw new MessageDeliverException("No recipients registered for the input message type.");
}
// Rent the array and also assign it to a span, which will be used to access values.
@@ -704,7 +704,7 @@ public TMessage UnsafeSend(TMessage message, TToken token)
if (i == 0)
{
- throw new InvalidOperationException("No recipients registered for the input message type and token.");
+ throw new MessageDeliverException("No recipients registered for the input message type and token.");
}
}
}
diff --git a/Source/Euonia.Bus.RabbitMq/RabbitMqDispatcher.cs b/Source/Euonia.Bus.RabbitMq/RabbitMqDispatcher.cs
index 8496189..2f80372 100644
--- a/Source/Euonia.Bus.RabbitMq/RabbitMqDispatcher.cs
+++ b/Source/Euonia.Bus.RabbitMq/RabbitMqDispatcher.cs
@@ -1,9 +1,11 @@
-using Microsoft.Extensions.Logging;
+using System.Net.Sockets;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Polly;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
+using RabbitMQ.Client.Exceptions;
namespace Nerosoft.Euonia.Bus.RabbitMq;
@@ -45,7 +47,8 @@ public async Task PublishAsync(RoutedMessage message, Cancel
props.Headers[Constants.MessageHeaders.MessageType] = typeName;
props.Type = typeName;
- await Policy.Handle()
+ await Policy.Handle()
+ .Or()
.WaitAndRetryAsync(_options.MaxFailureRetries, _ => TimeSpan.FromSeconds(3), (exception, _, retryCount, _) =>
{
_logger.LogError(exception, "Retry:{RetryCount}, {Message}", retryCount, exception.Message);
@@ -66,21 +69,9 @@ public async Task SendAsync(RoutedMessage message, Cancellat
{
using var channel = _connection.CreateChannel();
- {
- var queueDeclare = channel.DeclareQueuePassively($"{_options.QueueName}${message.Channel}$");
+ var requestQueueName = $"{_options.QueueName}${message.Channel}$";
- if (queueDeclare == null)
- {
- throw new InvalidOperationException("Channel not found in vhost '/'.");
- //channel.QueueDeclare($"{_options.QueueName}${message.Channel}$", true, false, false, null);
- //channel.BasicQos(0, 1, false);
- }
-
- if (queueDeclare.ConsumerCount < 1)
- {
- throw new InvalidOperationException("No consumer found for the channel.");
- }
- }
+ CheckQueue(channel, requestQueueName);
var typeName = message.GetTypeName();
@@ -89,7 +80,8 @@ public async Task SendAsync(RoutedMessage message, Cancellat
props.Headers[Constants.MessageHeaders.MessageType] = typeName;
props.Type = typeName;
- await Policy.Handle()
+ await Policy.Handle()
+ .Or()
.WaitAndRetryAsync(_options.MaxFailureRetries, _ => TimeSpan.FromSeconds(3), (exception, _, retryCount, _) =>
{
_logger.LogError(exception, "Retry:{RetryCount}, {Message}", retryCount, exception.Message);
@@ -98,7 +90,7 @@ await Policy.Handle()
{
var messageBody = await SerializeAsync(message, cancellationToken);
- channel.BasicPublish("", $"{_options.QueueName}${message.Channel}$", props, messageBody);
+ channel.BasicPublish("", requestQueueName, props, messageBody);
Delivered?.Invoke(this, new MessageDispatchedEventArgs(message.Data, null));
});
@@ -113,21 +105,7 @@ public async Task SendAsync(RoutedMessage SendAsync(RoutedMessage()
+ await Policy.Handle()
+ .Or()
.WaitAndRetryAsync(_options.MaxFailureRetries, _ => TimeSpan.FromSeconds(1), (exception, _, retryCount, _) =>
{
_logger.LogError(exception, "Retry:{RetryCount}, {Message}", retryCount, exception.Message);
@@ -175,6 +154,21 @@ void OnReceived(object sender, BasicDeliverEventArgs args)
}
}
+ private static void CheckQueue(IModel channel, string requestQueueName)
+ {
+ var queueDeclare = channel.DeclareQueuePassively(requestQueueName);
+
+ if (queueDeclare == null)
+ {
+ throw new MessageDeliverException("Channel not found in vhost '/'.");
+ }
+
+ if (queueDeclare.ConsumerCount < 1)
+ {
+ throw new MessageDeliverException("No consumer found for the channel.");
+ }
+ }
+
///
/// Serializes the message to bytes.
///
diff --git a/Source/Euonia.Bus.RabbitMq/RabbitMqRecipientRegistrar.cs b/Source/Euonia.Bus.RabbitMq/RabbitMqRecipientRegistrar.cs
index 137fdbd..695f5b5 100644
--- a/Source/Euonia.Bus.RabbitMq/RabbitMqRecipientRegistrar.cs
+++ b/Source/Euonia.Bus.RabbitMq/RabbitMqRecipientRegistrar.cs
@@ -37,7 +37,7 @@ public async Task RegisterAsync(IEnumerable registrations,
}
else
{
- throw new InvalidOperationException();
+ throw new InvalidOperationException("The message type is neither a queue nor a topic.");
}
recipient.Start(registration.Channel);
diff --git a/Source/Euonia.Bus/BusConfigurator.cs b/Source/Euonia.Bus/BusConfigurator.cs
index 38cf9d4..b89c76f 100644
--- a/Source/Euonia.Bus/BusConfigurator.cs
+++ b/Source/Euonia.Bus/BusConfigurator.cs
@@ -13,7 +13,7 @@ public class BusConfigurator : IBusConfigurator
{
private readonly List _registrations = new();
- private MessageConventionBuilder ConventionBuilder { get; } = new();
+ internal MessageConventionBuilder ConventionBuilder { get; } = new();
///
/// Gets the message handle registrations.
@@ -166,7 +166,6 @@ public BusConfigurator RegisterHandlers(IEnumerable types)
public BusConfigurator SetConventions(Action configure)
{
configure?.Invoke(ConventionBuilder);
- Service.TryAddSingleton(ConventionBuilder.Convention);
return this;
}
}
\ No newline at end of file
diff --git a/Source/Euonia.Bus/Core/ServiceBus.cs b/Source/Euonia.Bus/Core/ServiceBus.cs
index 8d21501..b87ded0 100644
--- a/Source/Euonia.Bus/Core/ServiceBus.cs
+++ b/Source/Euonia.Bus/Core/ServiceBus.cs
@@ -43,7 +43,7 @@ public Task PublishAsync(TMessage message, PublishOptions options, Act
if (!_convention.IsTopicType(message.GetType()))
{
- throw new InvalidOperationException("The message type is not an event type.");
+ throw new MessageTypeException("The message type is not an event type.");
}
var context = GetRequestContext();
@@ -66,7 +66,7 @@ public Task SendAsync(TMessage message, SendOptions options, Action SendAsync(TMessage message, SendOptions
if (!_convention.IsQueueType(message.GetType()))
{
- throw new InvalidOperationException("The message type is not a queue type.");
+ throw new MessageTypeException("The message type is not a queue type.");
}
var context = GetRequestContext();
diff --git a/Source/Euonia.Bus/ServiceCollectionExtensions.cs b/Source/Euonia.Bus/ServiceCollectionExtensions.cs
index 0fa56fe..5030abd 100644
--- a/Source/Euonia.Bus/ServiceCollectionExtensions.cs
+++ b/Source/Euonia.Bus/ServiceCollectionExtensions.cs
@@ -29,7 +29,7 @@ public static void AddServiceBus(this IServiceCollection services, Action();
+ services.TryAddSingleton(configurator.ConventionBuilder.Convention);
services.AddSingleton();
services.AddHostedService();
}
diff --git a/Source/Euonia.Business/Rules/DataAnnotationRule.cs b/Source/Euonia.Business/Rules/DataAnnotationRule.cs
index bda22ae..82c5d05 100644
--- a/Source/Euonia.Business/Rules/DataAnnotationRule.cs
+++ b/Source/Euonia.Business/Rules/DataAnnotationRule.cs
@@ -1,5 +1,7 @@
using System.ComponentModel.DataAnnotations;
+using ValidationResult = System.ComponentModel.DataAnnotations.ValidationResult;
+
namespace Nerosoft.Euonia.Business;
///
diff --git a/Source/Euonia.Core/Exceptions/BadGatewayException.cs b/Source/Euonia.Core/Exceptions/BadGatewayException.cs
index 609ea1e..2548c03 100644
--- a/Source/Euonia.Core/Exceptions/BadGatewayException.cs
+++ b/Source/Euonia.Core/Exceptions/BadGatewayException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur when a server acting as a gateway or proxy received an invalid response
diff --git a/Source/Euonia.Core/Exceptions/BadRequestException.cs b/Source/Euonia.Core/Exceptions/BadRequestException.cs
index d809cb5..8f3f991 100644
--- a/Source/Euonia.Core/Exceptions/BadRequestException.cs
+++ b/Source/Euonia.Core/Exceptions/BadRequestException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if request is bad.
diff --git a/Source/Euonia.Core/Exceptions/BusinessException.cs b/Source/Euonia.Core/Exceptions/BusinessException.cs
index 3bd7b0e..450f3d5 100644
--- a/Source/Euonia.Core/Exceptions/BusinessException.cs
+++ b/Source/Euonia.Core/Exceptions/BusinessException.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur during business logic execution.
diff --git a/Source/Euonia.Core/Exceptions/ConfigurationException.cs b/Source/Euonia.Core/Exceptions/ConfigurationException.cs
index 8e0fa4c..9454633 100644
--- a/Source/Euonia.Core/Exceptions/ConfigurationException.cs
+++ b/Source/Euonia.Core/Exceptions/ConfigurationException.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur during application configuration.
diff --git a/Source/Euonia.Core/Exceptions/ConflictException.cs b/Source/Euonia.Core/Exceptions/ConflictException.cs
index b688818..0407ca8 100644
--- a/Source/Euonia.Core/Exceptions/ConflictException.cs
+++ b/Source/Euonia.Core/Exceptions/ConflictException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if conflict.
diff --git a/Source/Euonia.Core/Exceptions/ExceptionPrompt.cs b/Source/Euonia.Core/Exceptions/ExceptionPrompt.cs
index f7e99fc..f8e4f5c 100644
--- a/Source/Euonia.Core/Exceptions/ExceptionPrompt.cs
+++ b/Source/Euonia.Core/Exceptions/ExceptionPrompt.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Responsible for storing and returning exception prompts.
diff --git a/Source/Euonia.Core/Exceptions/ForbiddenException.cs b/Source/Euonia.Core/Exceptions/ForbiddenException.cs
index 88f9fd2..bfa814e 100644
--- a/Source/Euonia.Core/Exceptions/ForbiddenException.cs
+++ b/Source/Euonia.Core/Exceptions/ForbiddenException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if request is denied.
diff --git a/Source/Euonia.Core/Exceptions/GatewayTimeoutException.cs b/Source/Euonia.Core/Exceptions/GatewayTimeoutException.cs
index 83ccc2b..3997440 100644
--- a/Source/Euonia.Core/Exceptions/GatewayTimeoutException.cs
+++ b/Source/Euonia.Core/Exceptions/GatewayTimeoutException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if gateway timeout.
diff --git a/Source/Euonia.Core/Exceptions/HttpStatusCodeAttribute.cs b/Source/Euonia.Core/Exceptions/HttpStatusCodeAttribute.cs
index 3400d05..6e0367f 100644
--- a/Source/Euonia.Core/Exceptions/HttpStatusCodeAttribute.cs
+++ b/Source/Euonia.Core/Exceptions/HttpStatusCodeAttribute.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
diff --git a/Source/Euonia.Core/Exceptions/HttpStatusException.cs b/Source/Euonia.Core/Exceptions/HttpStatusException.cs
index 8206dc3..cc2ba9a 100644
--- a/Source/Euonia.Core/Exceptions/HttpStatusException.cs
+++ b/Source/Euonia.Core/Exceptions/HttpStatusException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur when HTTP status code is not 200.
diff --git a/Source/Euonia.Core/Exceptions/IExceptionPrompt.cs b/Source/Euonia.Core/Exceptions/IExceptionPrompt.cs
index 3274be1..05169b2 100644
--- a/Source/Euonia.Core/Exceptions/IExceptionPrompt.cs
+++ b/Source/Euonia.Core/Exceptions/IExceptionPrompt.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// To be added.
diff --git a/Source/Euonia.Core/Exceptions/InternalServerErrorException.cs b/Source/Euonia.Core/Exceptions/InternalServerErrorException.cs
index 60488c4..958b579 100644
--- a/Source/Euonia.Core/Exceptions/InternalServerErrorException.cs
+++ b/Source/Euonia.Core/Exceptions/InternalServerErrorException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents the exception that is thrown when an internal server error occurs.
diff --git a/Source/Euonia.Core/Exceptions/InvalidValueException.cs b/Source/Euonia.Core/Exceptions/InvalidValueException.cs
index fe260ae..373ebaa 100644
--- a/Source/Euonia.Core/Exceptions/InvalidValueException.cs
+++ b/Source/Euonia.Core/Exceptions/InvalidValueException.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents the errors occurring when a value is invalid.
diff --git a/Source/Euonia.Core/Exceptions/MethodNotAllowedException.cs b/Source/Euonia.Core/Exceptions/MethodNotAllowedException.cs
index 56f1fc7..acb887d 100644
--- a/Source/Euonia.Core/Exceptions/MethodNotAllowedException.cs
+++ b/Source/Euonia.Core/Exceptions/MethodNotAllowedException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if request method is not allowed.
diff --git a/Source/Euonia.Core/Exceptions/NotFoundException.cs b/Source/Euonia.Core/Exceptions/NotFoundException.cs
index b89ba02..c5370f7 100644
--- a/Source/Euonia.Core/Exceptions/NotFoundException.cs
+++ b/Source/Euonia.Core/Exceptions/NotFoundException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if data is not found.
diff --git a/Source/Euonia.Core/Exceptions/RequestTimeoutException.cs b/Source/Euonia.Core/Exceptions/RequestTimeoutException.cs
index 7b529eb..a7450b6 100644
--- a/Source/Euonia.Core/Exceptions/RequestTimeoutException.cs
+++ b/Source/Euonia.Core/Exceptions/RequestTimeoutException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if request timeout.
diff --git a/Source/Euonia.Core/Exceptions/ServiceUnavailableException.cs b/Source/Euonia.Core/Exceptions/ServiceUnavailableException.cs
index 26d77dd..0a93e36 100644
--- a/Source/Euonia.Core/Exceptions/ServiceUnavailableException.cs
+++ b/Source/Euonia.Core/Exceptions/ServiceUnavailableException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if service is unavailable.
diff --git a/Source/Euonia.Core/Exceptions/TooManyRequestsException.cs b/Source/Euonia.Core/Exceptions/TooManyRequestsException.cs
index 6e1ef61..f95e86f 100644
--- a/Source/Euonia.Core/Exceptions/TooManyRequestsException.cs
+++ b/Source/Euonia.Core/Exceptions/TooManyRequestsException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if too many requests.
diff --git a/Source/Euonia.Core/Exceptions/UpgradeRequiredException.cs b/Source/Euonia.Core/Exceptions/UpgradeRequiredException.cs
index fda8a82..60ad60a 100644
--- a/Source/Euonia.Core/Exceptions/UpgradeRequiredException.cs
+++ b/Source/Euonia.Core/Exceptions/UpgradeRequiredException.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents errors that occur if upgrade required.
diff --git a/Source/Euonia.Core/Exceptions/ValidationException.cs b/Source/Euonia.Core/Exceptions/ValidationException.cs
index b92eee6..c49b203 100644
--- a/Source/Euonia.Core/Exceptions/ValidationException.cs
+++ b/Source/Euonia.Core/Exceptions/ValidationException.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// Represents the exception that is thrown when given data is not valid.
diff --git a/Source/Euonia.Core/Exceptions/ValidationResult.cs b/Source/Euonia.Core/Exceptions/ValidationResult.cs
index 0ca8d6a..b27af99 100644
--- a/Source/Euonia.Core/Exceptions/ValidationResult.cs
+++ b/Source/Euonia.Core/Exceptions/ValidationResult.cs
@@ -1,4 +1,4 @@
-namespace Nerosoft.Euonia.Core;
+namespace System;
///
/// The validation result.
diff --git a/Source/Euonia.Modularity/Extensions/ServiceProviderExtensions.cs b/Source/Euonia.Modularity/Extensions/ServiceProviderExtensions.cs
index 134b3a6..0533c88 100644
--- a/Source/Euonia.Modularity/Extensions/ServiceProviderExtensions.cs
+++ b/Source/Euonia.Modularity/Extensions/ServiceProviderExtensions.cs
@@ -12,7 +12,7 @@ public static class ServiceProviderExtensions
/// The registered service name.
/// The service type.
///
- public static TService GetService(this IServiceProvider provider, string name)
+ public static TService GetNamedService(this IServiceProvider provider, string name)
where TService : class
{
var @delegate = (NamedService)provider.GetService(typeof(NamedService));
@@ -27,7 +27,7 @@ public static TService GetService(this IServiceProvider provider, stri
/// The service type.
///
/// Throws if service with specified name was not resolved.
- public static TService GetRequiredService(this IServiceProvider provider, string name)
+ public static TService GetNamedRequiredService(this IServiceProvider provider, string name)
where TService : class
{
var @delegate = (NamedService)provider.GetService(typeof(NamedService));
diff --git a/Source/Euonia.Repository.EfCore/DataContextBase.cs b/Source/Euonia.Repository.EfCore/DataContextBase.cs
index d70a0cf..058dbfd 100644
--- a/Source/Euonia.Repository.EfCore/DataContextBase.cs
+++ b/Source/Euonia.Repository.EfCore/DataContextBase.cs
@@ -10,261 +10,182 @@ namespace Nerosoft.Euonia.Repository.EfCore;
///
public abstract class DataContextBase : DbContext, IRepositoryContext
- where TContext : DbContext, IRepositoryContext
+ where TContext : DbContext, IRepositoryContext
{
- private readonly ILogger _logger;
+ ///
+ protected DataContextBase(DbContextOptions options)
+ : base(options)
+ {
+ Id = Guid.NewGuid();
+ }
- ///
- protected DataContextBase(DbContextOptions options, ILoggerFactory factory)
- : base(options)
- {
- _logger = factory.CreateLogger();
- }
-
- ///
- /// Gets a value indicate whether the entry values are automatically set or not.
- ///
- protected abstract bool AutoSetEntryValues { get; }
-
- ///
- /// Gets a value indicate whether the domain events publishing are enabled or not.
- ///
- protected abstract bool EnabledPublishEvents { get; }
+ ///
+ /// Gets a value indicate whether the entry values are automatically set or not.
+ ///
+ protected abstract bool AutoSetEntryValues { get; }
///
/// Gets the kind of the date time.
///
protected virtual DateTimeKind DateTimeKind { get; } = DateTimeKind.Unspecified;
- ///
- public override int SaveChanges()
- {
- return SaveChanges(true);
- }
-
- ///
- public override int SaveChanges(bool acceptAllChangesOnSuccess)
- {
- var entries = ChangeTracker.Entries();
- var events = GetTrackedEvents(entries);
- SetEntryValues(entries);
- var result = base.SaveChanges(acceptAllChangesOnSuccess);
- if (result > 0 && events.Any())
- {
- PublishEvents(events);
- }
-
- return result;
- }
-
- #region Implementation of IRepositoryContext
-
- ///
- ///
- ///
- public Guid Id => Guid.NewGuid();
-
- ///
- ///
- ///
- public virtual string Provider => Database.ProviderName;
+ ///
+ public override int SaveChanges()
+ {
+ return SaveChanges(true);
+ }
- ///
- public IQueryable SetOf()
- where TEntity : class
- {
- return Set();
- }
+ ///
+ public override int SaveChanges(bool acceptAllChangesOnSuccess)
+ {
+ var entries = ChangeTracker.Entries();
+ SetEntryValues(entries);
+ var result = base.SaveChanges(acceptAllChangesOnSuccess);
+ return result;
+ }
- ///
- public IDbConnection GetConnection()
- {
- return Database.GetDbConnection();
- }
+ #region Implementation of IRepositoryContext
- ///
- public IDbTransaction GetTransaction()
- {
- return Database.CurrentTransaction?.GetDbTransaction();
- }
+ ///
+ ///
+ ///
+ public Guid Id { get; }
- ///
- public async Task RollbackAsync(CancellationToken cancellationToken = default)
- {
- await Database.RollbackTransactionAsync(cancellationToken);
- }
+ ///
+ ///
+ ///
+ public virtual string Provider => Database.ProviderName;
+
+ ///
+ public IQueryable SetOf()
+ where TEntity : class
+ {
+ return Set();
+ }
+
+ ///
+ public IDbConnection GetConnection()
+ {
+ return Database.GetDbConnection();
+ }
+
+ ///
+ public IDbTransaction GetTransaction()
+ {
+ return Database.CurrentTransaction?.GetDbTransaction();
+ }
+
+ ///
+ public async Task RollbackAsync(CancellationToken cancellationToken = default)
+ {
+ await Database.RollbackTransactionAsync(cancellationToken);
+ }
#endregion
///
public override async Task SaveChangesAsync(CancellationToken cancellationToken = default)
- {
- return await SaveChangesAsync(true, cancellationToken);
- }
-
- ///
- public override async Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
- {
- var entries = ChangeTracker.Entries();
- var events = GetTrackedEvents(entries);
- SetEntryValues(entries);
- var result = await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
- if (result > 0 && events.Any())
- {
- PublishEvents(events);
- }
-
- return result;
- }
-
- ///
- ///
- ///
- ///
- ///
- protected virtual IEnumerable GetTrackedEvents(IEnumerable entries)
- {
- var events = new List();
-
- foreach (var entry in entries)
- {
- if (entry.Entity is not IHasDomainEvents aggregate)
- {
- continue;
- }
-
- aggregate.AttachToEvents();
- events.AddRange(aggregate.GetEvents());
- aggregate.ClearEvents();
- }
+ {
+ return await SaveChangesAsync(true, cancellationToken);
+ }
+
+ ///
+ public override async Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
+ {
+ var entries = ChangeTracker.Entries();
+ SetEntryValues(entries);
+ var result = await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
+ return result;
+ }
- return events;
- }
-
- ///
- /// Sets the entry values.
- ///
- ///
- protected virtual void SetEntryValues(IEnumerable entries)
- {
- if (!AutoSetEntryValues)
- {
- return;
- }
-
- foreach (var entry in entries)
- {
+ ///
+ /// Sets the entry values.
+ ///
+ ///
+ protected virtual void SetEntryValues(IEnumerable entries)
+ {
+ if (!AutoSetEntryValues)
+ {
+ return;
+ }
+
+ foreach (var entry in entries)
+ {
var time = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);
switch (entry.State)
- {
- case EntityState.Added:
- if (entry.Entity is IHasCreateTime)
- {
- entry.CurrentValues[nameof(IHasCreateTime.CreateTime)] = time;
- }
-
- if (entry.Entity is IHasUpdateTime)
- {
- entry.CurrentValues[nameof(IHasUpdateTime.UpdateTime)] = time;
- }
-
- if (entry.Entity is ITombstone)
- {
- entry.CurrentValues[nameof(ITombstone.IsDeleted)] = false;
- }
-
- break;
- case EntityState.Deleted:
- if (entry.Entity is ITombstone)
- {
- entry.State = EntityState.Modified;
- entry.CurrentValues[nameof(ITombstone.IsDeleted)] = true;
- entry.CurrentValues[nameof(ITombstone.DeleteTime)] = time;
- }
-
- break;
- case EntityState.Detached:
- break;
- case EntityState.Unchanged:
- break;
- case EntityState.Modified:
- SetModifiedEntry(entry, time);
-
- break;
- default:
- continue;
- }
- }
- }
-
- private static void SetModifiedEntry(EntityEntry entry, DateTime time)
- {
- if (entry.State != EntityState.Modified)
- {
- return;
- }
-
- // ReSharper disable once ConvertIfStatementToSwitchStatement
- if (entry.Entity is ITombstone { IsDeleted: true })
- {
- entry.CurrentValues[nameof(ITombstone.IsDeleted)] = true;
- entry.CurrentValues[nameof(ITombstone.DeleteTime)] = time;
- return;
- }
-
- if (entry.Entity is IHasUpdateTime)
- {
- entry.CurrentValues[nameof(IHasUpdateTime.UpdateTime)] = time;
- }
- }
-
- ///
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- foreach (var entityType in modelBuilder.Model.GetEntityTypes())
- {
- //other automated configurations left out
- if (typeof(ITombstone).IsAssignableFrom(entityType.ClrType))
- {
- entityType.SetTombstoneQueryFilter();
- }
- }
- }
-
- ///
- /// Publishes the domain events.
- ///
- ///
- protected virtual void PublishEvents(IEnumerable events)
- {
- if (!EnabledPublishEvents)
- {
- return;
- }
-
- try
- {
- async void Action(DomainEvent @event)
- {
- await PublishEventAsync(@event);
- }
-
- Parallel.ForEach(events, Action);
- }
- catch (Exception exception)
- {
- _logger.LogError(exception, "PublishEvents Error");
- Debug.WriteLine(exception);
- }
- }
-
- ///
- /// Publishes the domain event asynchronously.
- ///
- ///
- ///
- ///
- protected abstract Task PublishEventAsync(TEvent @event)
- where TEvent : DomainEvent;
+ {
+ case EntityState.Added:
+ if (entry.Entity is IHasCreateTime)
+ {
+ entry.CurrentValues[nameof(IHasCreateTime.CreateTime)] = time;
+ }
+
+ if (entry.Entity is IHasUpdateTime)
+ {
+ entry.CurrentValues[nameof(IHasUpdateTime.UpdateTime)] = time;
+ }
+
+ if (entry.Entity is ITombstone)
+ {
+ entry.CurrentValues[nameof(ITombstone.IsDeleted)] = false;
+ }
+
+ break;
+ case EntityState.Deleted:
+ if (entry.Entity is ITombstone)
+ {
+ entry.State = EntityState.Modified;
+ entry.CurrentValues[nameof(ITombstone.IsDeleted)] = true;
+ entry.CurrentValues[nameof(ITombstone.DeleteTime)] = time;
+ }
+
+ break;
+ case EntityState.Detached:
+ break;
+ case EntityState.Unchanged:
+ break;
+ case EntityState.Modified:
+ SetModifiedEntry(entry, time);
+
+ break;
+ default:
+ continue;
+ }
+ }
+ }
+
+ private static void SetModifiedEntry(EntityEntry entry, DateTime time)
+ {
+ if (entry.State != EntityState.Modified)
+ {
+ return;
+ }
+
+ // ReSharper disable once ConvertIfStatementToSwitchStatement
+ if (entry.Entity is ITombstone { IsDeleted: true })
+ {
+ entry.CurrentValues[nameof(ITombstone.IsDeleted)] = true;
+ entry.CurrentValues[nameof(ITombstone.DeleteTime)] = time;
+ return;
+ }
+
+ if (entry.Entity is IHasUpdateTime)
+ {
+ entry.CurrentValues[nameof(IHasUpdateTime.UpdateTime)] = time;
+ }
+ }
+
+ ///
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ foreach (var entityType in modelBuilder.Model.GetEntityTypes())
+ {
+ //other automated configurations left out
+ if (typeof(ITombstone).IsAssignableFrom(entityType.ClrType))
+ {
+ entityType.SetTombstoneQueryFilter();
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/Source/Euonia.Validation/DefaultValidator.cs b/Source/Euonia.Validation/DefaultValidator.cs
index 1a6343a..25cbe5b 100644
--- a/Source/Euonia.Validation/DefaultValidator.cs
+++ b/Source/Euonia.Validation/DefaultValidator.cs
@@ -1,7 +1,6 @@
using FluentValidation;
-using Nerosoft.Euonia.Core;
-using ValidationException = Nerosoft.Euonia.Core.ValidationException;
+using ValidationException = System.ValidationException;
namespace Nerosoft.Euonia.Validation;
diff --git a/project.props b/project.props
index 5e21625..6ae9c62 100644
--- a/project.props
+++ b/project.props
@@ -1,6 +1,6 @@
- 8.1.0
+ 8.1.1
damon
Nerosoft Ltd.
Euonia
@@ -8,6 +8,6 @@
enable
disable
latest
- CS2002;IDE0290;IDE0300;IDE0301;IDE0028
+ CS2002;IDE0290;IDE0300;IDE0301;IDE0305;IDE0028
\ No newline at end of file