private void ExecutingDomainCommand(AggregateRootMessagingContext context, IDomainCommand command) { var methodName = "OnDomainCommand"; var commandType = command.GetType(); var commandTypeFullName = command.GetType(); var domainCommandType = typeof(IDomainCommand); var aggregateTypeFullName = AggregateRootType.FullName; if (!domainCommandType.IsAssignableFrom(commandType)) { throw new MethodNotFoundException($"The method: {methodName}({commandTypeFullName}) in {aggregateTypeFullName} is wrong, reason: {commandTypeFullName} cannot assign to interface: {domainCommandType.FullName}."); } var methodWithoutContext = AggregateRootType .GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public, null, new[] { commandType }, null); if (methodWithoutContext != null) { var instance = Expression.Constant(this); var parameter = Expression.Parameter(commandType, methodName); var call = Expression.Call(instance, methodWithoutContext, parameter); var lambda = Expression.Lambda(call, parameter); var methodDelegate = lambda.Compile(); methodDelegate.DynamicInvoke(command); return; } var contextType = context.GetType(); var methodWithContext = AggregateRootType .GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public, null, new[] { contextType, commandType }, null); if (methodWithContext != null) { var instance = Expression.Constant(this); var parameter1 = Expression.Parameter(contextType, $"{methodName}_0"); var parameter2 = Expression.Parameter(commandType, $"{methodName}_1"); var call = Expression.Call(instance, methodWithContext, parameter1, parameter2); var lambda = Expression.Lambda(call, parameter1, parameter2); var methodDelegate = lambda.Compile(); methodDelegate.DynamicInvoke(context, command); return; } throw new MethodNotFoundException($"No {methodName}({commandTypeFullName}) found in {aggregateTypeFullName}."); }
public virtual DomainCommandResult HandleDomainCommand(AggregateRootMessagingContext context, IDomainCommand command) { var aggregateRootId = command.AggregateRootId; var domainCommandAggregateType = command.AggregateRootType; if (AggregateRootType != domainCommandAggregateType) { return(DomainCommandResult.Failed(command.Id, $"Incorrect the aggregate root type, expected: {AggregateRootType.FullName}, actual: {domainCommandAggregateType.FullName}")); } if (!string.IsNullOrWhiteSpace(Id) && Id != aggregateRootId) { return(DomainCommandResult.Failed(command.Id, $"Incorrect the aggregate root id, expected: {Id}, actual: {aggregateRootId}")); } ExecutingDomainCommand(context, command); return(DomainCommandResult.Succeed(command.Id)); }