lucabriguglia / opencqrs Goto Github PK
View Code? Open in Web Editor NEW.NET Standard framework to create simple and clean design. Advanced features for DDD, CQRS and Event Sourcing.
License: Apache License 2.0
.NET Standard framework to create simple and clean design. Advanced features for DDD, CQRS and Event Sourcing.
License: Apache License 2.0
This is a question rather than issue.
As far as I was able to read from the source code, when the events are produced by the aggregate then they are saved in event store and published by the event publisher:
public void SendAndPublish<TCommand, TAggregate>(TCommand command)
where TCommand : IDomainCommand
where TAggregate : IAggregateRoot
{
if (command == null)
throw new ArgumentNullException(nameof(command));
var handler = _handlerResolver.ResolveHandler<ICommandHandlerWithDomainEvents<TCommand>>();
_commandStore.SaveCommand<TAggregate>(command);
var events = handler.Handle(command);
foreach (var @event in events)
{
@event.CommandId = command.Id;
var concreteEvent = _eventFactory.CreateConcreteEvent(@event);
_eventStore.SaveEvent<TAggregate>((IDomainEvent)concreteEvent);
_eventPublisher.Publish(concreteEvent);
}
}
This comes to me with an conclusion that there is no transaction during saving these events to the event store either publishing then on the bus / updating read model.
When save of single event will fail then save of previous ones will not be compensated. Similar situstion os without read model. Can you confirm that?
Hi,
I'm having problem with following class from my domain project
public class BaseVenueValidator<T> : AbstractValidator<T> where T : BaseVenueCommand
{
private readonly IVenueRules _venueRules;
public BaseVenueValidator(IVenueRules venueRules)
{
_venueRules = venueRules;
RuleFor(c => c.VenueId)
.NotEmpty().WithMessage("Brak Id Lokalu!")
.Must(BeAnExistingVenue).WithMessage("Lokal nie istnieje w bazie!");
}
private bool BeAnExistingVenue(Guid venueId)
{
return _venueRules.DoesVenueExist(venueId);
}
}
and the baseValueCommand class:
public class BaseVenueCommand: DomainCommand { public Guid VenueId { get; set; } }
I'm using AbstractValidator from FluentValidation. I'm getting following exception on application startup: 'Gastro.Domain.BaseVenueValidator
1[T]' violates the constraint of type parameter 'T'`.
I guess there's some problem with scurtors register as implemented interfaces method that you are using in addWeapsyCqrs method. Is it possible to somehow fix this issue? I'm using dotnet core 2.1 and latest version of WeapsyCqrs
An AutoMapper mapper configuration to create a concrete event object is currently created on the fly for each event after a command has been handled in order to save and/or publish the event itself.
It's an expensive operation and because all event types are already known at the startup time, I'm going to create a single mapper configuration and register all mappings when register the services.
The project will be renamed to Weapsy.CQRS and the single interface to use will be IDispatcher.
Since there is support for ASB already: https://kafka.apache.org/
Hi - I am looking for the simple CQRS .NET Core framework. Are there plans to support Event Grid instead of Azure Service Bus? How much of a work is it to get the EventGrid plugged in if I take it on my own?
Rinat
Do you have an example of using OpenCQRS using console app? I have been trying to put on example together but I notice that I get an error since OpenCQRS wants to access an instance of the IHttpContextAccessor to access the publisher. Any idea how I can set up OpenCQRS in a console app to execute commands and publish any events?
I love what you guys have done with this project. However, due to it being licensed as GPL, our company cannot adopt this into our software. I wish it was licensed as MIT or Apache.
Just an FYI. I'm probably not alone in this camp.
WebAPI project, core 2.1.1.
Store the commands the same way the library currently does for the events, using any of the available data providers.
Hi,
does it work for local mongodb, for example, to work in a development/local environment, or I must have a mongodb on azure with cosmosdb? I mean, for production I will use for sure cosmosdb, but I need a local mongodb for development.
Thanks!
Hi bro,
I've been writing a series of posts about microservices and in the last one, I used your Weapsy.CQRS project, that btw is very nice, so, this is the link if you wanted to share it.
Maintenance is hard, should I completely remove them?
If I placed this confidential logic in command handler. This data also writes in event store, table DomainCommand.
It should be additional layer for all logic (some services), and Commands/Events only updates storages ?
Change domain event UserId type from Guid to string to be more flexible.
Now it's look like
"ServiceBusConfiguration": {
"ConnectionString": "Endpoint=sb://"
},
"DomainDbConfiguration": {
"ConnectionString": "Data Source=.\;"
},
"ConnectionStrings": {
"SqlConnection": "Data Source=.\"
},
For applications published on Azure connection strings are hidden, so better to put them under correct object.
"ConnectionStrings": {
"SqlConnection": "Data Source=.\",
"DomainDbConfiguration": Data Source=.\;",
"ServiceBusConfiguration": "Endpoint=sb://"
},
Add DispatchAsync (IBusMessage) method to IDispatcher
Event history is loaded during GetById method, so fast indexed query is a requirement.
Add IDomainCommand as suggested by @andreujuanc
Splitting Weapsy.EventStore.EF into multiple packages to avoid dependencies on other data providers.
New packages will be:
Hello,
This idea might be really hard to implement: what if IDispatcher were simpler?
There are basically 4 flavours for the dispatcher to dispatch a ICommand:
In this case, the person who is executing the action has to know exactly what to use regarding the actual actual implementation of the command.
We could make HandlerResolver, CommandSender, etc, smarter about this, so that it knows what to call based on the command's interfaces?
More over: should the caller dedice if the Events are published or not?
So SendAndPublishAsync
should be a thing? or should it be based on wether the the handler implementation task returns events?
I will try to create a "demo" of this, to get the feel for it in my fork. Will post link if idea seems duable/reasonable.
PS: Feel free to close this issue if it goes beyond the scope of this project.
Cheers.
I'm playing around with this project in a console app. I found out that there is a small issue in Weapsy.Cqrs.Extensions.ServiceCollectionExtensions
. You are not returning the instance of IServiceCollection
.
So that should become:
// changed void to IServiceCollection
public static IServiceCollection AddWeapsyCqrs(this IServiceCollection services, params Type[] types)
{
// code here...
return services; // You missed this one
}
So far everything looks good. Only problem I have is a way to replay all the events from the EventStore, so I can rebuild the state of my read database. Because in the EventStore database all the DomainAggregate Types are saved like this:
Weapsy.Cqrs.Domain.IAggregateRoot, Weapsy.Cqrs, Version=2.1.0.0, Culture=neutral, PublicKeyToken=null
Instead of the actual assemblyname of the domain class that implements the AggregateRoot
. So somewhere there is an issue there as well.
Funny thing is that I don't have that last problem (with the wrong assembly name in the DomainAggregate
table) when I download the source code and reference that directly in my project instead of using the Nuget package (using the Weapsy.Cqrs.EventStore.EF.Sqlite
2.1.0 version).
So it seems to be happening only in the Nuget package version.
I did make hangfire (fire and forget job), but nothing happened. For command/events execution needs context ?
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
at OpenCqrs.Dependencies.Resolver.ResolveT
at OpenCqrs.Dependencies.HandlerResolver.ResolveHandlerTHandler
at OpenCqrs.Queries.QueryProcessor.ProcessAsync[TQuery,TResult](TQuery query)
Hey bro,
Is this error familiar to you? I'm getting this error when I try to get an aggregate from event store (in my case, mongo) but isn't always happen, in my case is happening with 2 aggregates "records" the third one, works fine.
"ClassName": "System.InvalidCastException",
"Message": "Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Weapsy.Cqrs.Domain.DomainEvent'.",
"Data": null,
"InnerException": null,
"HelpURL": null,
"StackTraceString": " at Weapsy.Cqrs.EventStore.CosmosDB.MongoDB.EventStore.<GetEventsAsync>d__6.MoveNext()\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Weapsy.Cqrs.Domain.Repository`1.<GetByIdAsync>d__4.MoveNext()\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\n at Duber.Trip.API.Controllers.TripController.<GetTrip>d__6.MoveNext() in C:\\Users\\vany0\\OneDrive\\Documentos\\GitHub\\microservices\\src\\Application\\Duber.Trip.API\\Controllers\\TripController.cs:line 45\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__10.MoveNext()\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\n at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__14.MoveNext()\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextExceptionFilterAsync>d__23.MoveNext()",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": null,
"HResult": -2147467262,
"Source": "Weapsy.Cqrs.EventStore.CosmosDB.MongoDB",
"WatsonBuckets": null
}
As discussed IRL, it should be fairly trivial to add support for transactional processing on the service bus:
https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-transactions
Reduce the number of methods by adding only one method with an optional "options" parameter that will determine the behaviour in terms of saving commands and events in the domain stores, publish the events and eventually send the events to the message bus.
Hello,
I find this project amazing and so well implented. To bad noone made an inmemory implementation of the innerworkings.
Yes, there are some mocks and stuff in the test projects. But It'd be nice to have at least something pre-made, well-tested, to use in our unit tests.
I will try to implemented everything myself, but I'm adding this issue just in case someone already did or just as a reminder/feature-request.
PS: If I get something working I'll push it to some repo to see how well made is and maybe it can be the start point of the implementation.
Cheers
Since there is ASB support already: https://aws.amazon.com/sqs/
Support transactions across command handlers, event handlers and domain store.
This would be helpful in addressing situations that could have race conditions. This way the command handler can check if the aggregate has changed since the time the command was issued by the client.
int ExpectedVersion { get; }
Since there is support for ASB already: https://www.rabbitmq.com/
Hello, I'd like to ask if this project has any plans to support actor frameworks like Orleans or Akka?
Merge the following interfaces:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.