charlessolar / Aggregates.NET

.NET event sourced domain driven design model via NServiceBus and GetEventStore

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Isn't there a way to NOT use EventStore?

AbdoDabbas opened this issue · comments

I'm trying to build an application that uses SQL Server to read data from, so I don't need the EventStore to be used, I noticed in your example TodoDDD in the project Application which only needs the UnitOfWork and not EventStore, it also creates ES client and adds it to the endpoint configuration.

Why do I need to initialize ES if I will not use it? I tried not to it throws an exception:

2020-08-17 12:05:06.976 ERROR Moving message '4920b48b-5ac6-4e4f-a3fc-ac1a0095b7b1' to the error queue 'error' because processing failed due to an exception:
StructureMap.StructureMapConfigurationException: No default Instance is registered and cannot be automatically determined for type 'Aggregates.Contracts.IStoreEvents'

There is no configuration specified for Aggregates.Contracts.IStoreEvents

1.) new StoreEntities(*Default of IMetrics*, *Default of IStoreEvents*, *Default of IStoreSnapshots*, *Default of IOobWriter*, *Default of IEventFactory*, *Default of IVersionRegistrar*, *Default of ITrackChildren*)
2.) Aggregates.Internal.StoreEntities
3.) Instance of Aggregates.Contracts.IStoreEntities (Aggregates.Internal.StoreEntities)
4.) new RepositoryFactory(*Default of IStoreEntities*)
5.) Aggregates.Internal.RepositoryFactory
6.) Instance of Aggregates.Contracts.IRepositoryFactory (Aggregates.Internal.RepositoryFactory)
7.) Container.GetInstance<Aggregates.Contracts.IRepositoryFactory>()
8.) Lambda: Invoke(value(Aggregates.Internal.Container+<>c__DisplayClass7_0`1[Aggregates.UnitOfWork.IDomain]).factory, value(Aggregates.Internal.Container))
9.) Instance of Aggregates.UnitOfWork.IDomain
10.) Container.GetInstance<Aggregates.UnitOfWork.IDomain>()

   at lambda_method(Closure , IBuildSession , IContext )
   at StructureMap.Building.BuildPlan.Build(IBuildSession session, IContext context)
   at StructureMap.BuildSession.BuildNewInSession(Type pluginType, Instance instance)
   at StructureMap.Pipeline.ContainerSpecificObjectCache.buildWithSession(Type pluginType, Instance instance, IBuildSession session)
   at StructureMap.Pipeline.LifecycleObjectCache.<>c__DisplayClass5_0.<Get>b__0(Int32 _)
   at StructureMap.Pipeline.LazyLifecycleObjectCacheExtensions.<>c__DisplayClass1_1`2.<GetOrAdd>b__1()
   at StructureMap.Pipeline.LazyLifecycleObject`1.CreateValue()
   at StructureMap.Pipeline.LazyLifecycleObject`1.get_Value()
   at StructureMap.Pipeline.LazyLifecycleObjectCacheExtensions.GetOrAdd[TKey,TValue](ConcurrentDictionary`2 cache, TKey key, Func`2 valueFactory)
   at StructureMap.Pipeline.LifecycleObjectCache.Get(Type pluginType, Instance instance, IBuildSession session)
   at StructureMap.BuildSession.ResolveFromLifecycle(Type pluginType, Instance instance)
   at StructureMap.SessionCache.GetObject(Type pluginType, Instance instance, ILifecycle lifecycle)
   at StructureMap.SessionCache.GetDefault(Type pluginType, IPipelineGraph pipelineGraph)
   at StructureMap.BuildSession.GetInstance(Type pluginType)
   at StructureMap.Container.DoGetInstance(Type pluginType)
   at StructureMap.Container.GetInstance[T]()
   at Aggregates.Internal.Container.Resolve[TResolve]() in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.StructureMap\Internal\Container.cs:line 116
   at Aggregates.Internal.UnitOfWorkExecutor.Invoke(IIncomingLogicalMessageContext context, Func`1 next) in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.NServiceBus\Internal\UnitOfWorkExecutor.cs:line 52
   at Aggregates.Internal.CommandAcceptor.Invoke(IIncomingLogicalMessageContext context, Func`1 next) in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.NServiceBus\Internal\CommandAcceptor.cs:line 41
   at NServiceBus.ScheduledTaskHandlingBehavior.Invoke(IIncomingLogicalMessageContext context, Func`2 next)
   at NServiceBus.InvokeSagaNotFoundBehavior.Invoke(IIncomingLogicalMessageContext context, Func`2 next)
   at Aggregates.Internal.ExceptionRejector.Invoke(IIncomingLogicalMessageContext context, Func`1 next) in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.NServiceBus\Internal\ExceptionRejector.cs:line 48
   at Aggregates.Internal.ExceptionRejector.Invoke(IIncomingLogicalMessageContext context, Func`1 next) in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.NServiceBus\Internal\ExceptionRejector.cs:line 99
   at Aggregates.Internal.SagaBehaviour.Invoke(IIncomingLogicalMessageContext context, Func`1 next) in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.NServiceBus\Internal\SagaBehaviour.cs:line 31
   at NServiceBus.DeserializeMessageConnector.Invoke(IIncomingPhysicalMessageContext context, Func`2 stage)
   at NServiceBus.InvokeAuditPipelineBehavior.Invoke(IIncomingPhysicalMessageContext context, Func`2 next)
   at NServiceBus.ProcessingStatisticsBehavior.Invoke(IIncomingPhysicalMessageContext context, Func`2 next)
   at NServiceBus.TransportReceiveToPhysicalMessageConnector.Invoke(ITransportReceiveContext context, Func`2 next)
   at NServiceBus.MainPipelineExecutor.Invoke(MessageContext messageContext)
   at Aggregates.Internal.Dispatcher.SendLocal(IFullMessage message, IDictionary`2 headers) in D:\a\Aggregates.NET\Aggregates.NET\src\Aggregates.NET.NServiceBus\Internal\Dispatcher.cs:line 117
Exception details:
        Message ID: 4920b48b-5ac6-4e4f-a3fc-ac1a0095b7b1

Yes there is - the example is in the Presentation part of the project. The web api doesnt need to talk to event store so it uses the configuration option "SetPassive" like so

public static IServiceCollection AddAggregatesNet(this IServiceCollection services, EndpointConfiguration configuration)
        {
            Aggregates.Configuration.Build(c => c
                   .Microsoft(services)
                   .NewtonsoftJson()
                   .NServiceBus(configuration)
                   .SetUniqueAddress(Defaults.Instance.ToString())
                   .SetPassive()
                   .SetRetries(20)
               ).Wait();

            services.AddSingleton<IHostedService>(provider => new AggregatesService(provider));
            
            services.AddSingleton<IMessageSession>(_ => Aggregates.Bus.Instance);

            return services;
        }

SetPassive will not insert behaviors which communicate with event store and will not process commands or events.

Will events from eventstore not be updating the sql server? Typically thats the design. In the todo example the Application does still need EventStore - in fact it receives events to update its state via the store. Typically a sql server would need the same? Unless you are updating the sql database via some other process

I have this Application project which will need to listen to the events triggered in the domain model (via Apply<>) to update the read model, but I thought why to use the EventStore in the project? I can create handlers for all events that DM is triggering and update the DB using EF .
I couldn't link between using ES in my Application project and updating the SQL, can you please explain a little bit more? can't I just create handlers and wait for the events?

The clients like Application receive events from the event store. So it needs a connection to the event store to receive those events.

This diagram outlines the relationship
https://github.com/charlessolar/eShopOnContainersDDD/raw/master/img/overview.png