This repository was archived by the owner on Feb 6, 2025. It is now read-only.
-
Couldn't load subscription status.
- Fork 70
Ef Core support and Sample Web API using Saga with SQL Server #51
Open
UmerIftikhar
wants to merge
8
commits into
snatch-dev:master
Choose a base branch
from
UmerIftikhar:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
aafe246
Basic Example Added for handling the saga with EF core
4352416
Added Implementation for EFCore for Chronicle
951ef26
Updated the Readme for Custom Saga Implementation via EFCore
875ef5c
JSON Deserializer generic method used while converting the saga Data
370d7bf
fixed Data return type for Saga without TData
7a067e5
renamed the efcore test project
ea59c32
Internal Implementaion of EFCore changed
789e374
removed UNIT OF WORK
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/Chronicle.Integrations.EFCore/Chronicle.Integrations.EFCore.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>netcoreapp3.1</TargetFramework> | ||
| <Title>Chronicle.Integrations.EFCore</Title> | ||
| <AssemblyName>Chronicle.Integrations.EFCore</AssemblyName> | ||
| <PackageId>Chronicle_.Integrations.EFCore</PackageId> | ||
| <PackageTags>chronicle;saga;efcore</PackageTags> | ||
| <Description>Implementation of saga pattern for .NET Core</Description> | ||
| <Authors>Umer Iftikhar</Authors> | ||
| <VersionPrefix>3.1.1</VersionPrefix> | ||
| <Version>3.1.1</Version> | ||
| <AssemblyVersion>3.1.1</AssemblyVersion> | ||
| <FileVersion>3.1.1</FileVersion> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Chronicle_" Version="3.*" /> | ||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.0" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" /> | ||
| <PackageReference Include="System.Data.SqlClient" Version="4.8.0" /> | ||
| <PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.8" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
16 changes: 16 additions & 0 deletions
16
src/Chronicle.Integrations.EFCore/EntityConfigurations/ConfigureSagaTables.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Text; | ||
| using Microsoft.EntityFrameworkCore; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.EntityConfigurations | ||
| { | ||
| public static class ConfigureSagaTables | ||
| { | ||
| public static void Create(ModelBuilder modelBuilder) | ||
| { | ||
| modelBuilder.ApplyConfiguration(new SagaLogDataEntityTypeConfiguration()); | ||
| modelBuilder.ApplyConfiguration(new SagaStateEntityTypeConfiguration()); | ||
| } | ||
| } | ||
| } |
18 changes: 18 additions & 0 deletions
18
src/Chronicle.Integrations.EFCore/EntityConfigurations/SagaLogDataEntityTypeConfiguration.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Microsoft.EntityFrameworkCore.Metadata.Builders; | ||
| using Chronicle.Integrations.EFCore.Persistence; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.EntityConfigurations | ||
| { | ||
| internal class SagaLogDataEntityTypeConfiguration : IEntityTypeConfiguration<EFCoreSagaLogData> | ||
| { | ||
| public void Configure(EntityTypeBuilder<EFCoreSagaLogData> builder) | ||
| { | ||
| builder.ToTable("SagaLog", "dbo"); | ||
| builder.HasKey(c => c.LogId); | ||
| builder.Property(c => c.LogId).ValueGeneratedOnAdd(); | ||
| builder.Ignore(c => c.Id); | ||
| builder.Ignore(c => c.Message); | ||
| } | ||
| } | ||
| } |
17 changes: 17 additions & 0 deletions
17
src/Chronicle.Integrations.EFCore/EntityConfigurations/SagaStateEntityTypeConfiguration.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| using Chronicle.Integrations.EFCore.Persistence; | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Microsoft.EntityFrameworkCore.Metadata.Builders; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.EntityConfigurations | ||
| { | ||
| internal class SagaStateEntityTypeConfiguration : IEntityTypeConfiguration<EFCoreSagaStateData> | ||
| { | ||
| public void Configure(EntityTypeBuilder<EFCoreSagaStateData> builder) | ||
| { | ||
| builder.ToTable("SagaState", "dbo"); | ||
| builder.HasKey(r => r.SagaId); | ||
| builder.Ignore(c => c.Id); | ||
| builder.Ignore(c => c.Data); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Chronicle.Integrations.EFCore.Persistence; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore | ||
| { | ||
| public static class Extensions | ||
| { | ||
| public static IChronicleBuilder UseEFCorePersistence<TContext>(this IChronicleBuilder builder) | ||
| where TContext: DbContext | ||
| { | ||
| builder.UseSagaLog<EFCoreSagaLog<TContext>>(); | ||
| builder.UseSagaStateRepository<EFCoreSagaState<TContext>>(); | ||
|
|
||
| return builder; | ||
| } | ||
| } | ||
| } |
33 changes: 33 additions & 0 deletions
33
src/Chronicle.Integrations.EFCore/Persistence/EFCoreSagaLog.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Newtonsoft.Json; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.Persistence | ||
| { | ||
| internal class EFCoreSagaLog<TContext> : ISagaLog where TContext : DbContext | ||
| { | ||
| private readonly TContext _dbContext; | ||
|
|
||
| public EFCoreSagaLog(TContext dbContext) | ||
| { | ||
| _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); | ||
| } | ||
|
|
||
| public async Task<IEnumerable<ISagaLogData>> ReadAsync(SagaId id, Type type) | ||
| => await _dbContext.Set<EFCoreSagaLogData>() | ||
| .Where(sld => sld.SagaId == id.Id && sld.SagaType == type.FullName) | ||
| .ToArrayAsync(); | ||
|
|
||
| public async Task WriteAsync(ISagaLogData message) | ||
| { | ||
UmerIftikhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (null == message) | ||
| throw new ArgumentNullException(nameof(message)); | ||
| await _dbContext.Set<EFCoreSagaLogData>().AddAsync(new EFCoreSagaLogData(message.Id.Id, message.Type.ToString(), message.CreatedAt, JsonConvert.SerializeObject(message.Message))); | ||
| await _dbContext.SaveChangesAsync(); | ||
| } | ||
| } | ||
|
|
||
| } | ||
30 changes: 30 additions & 0 deletions
30
src/Chronicle.Integrations.EFCore/Persistence/EFCoreSagaLogData.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| using System; | ||
| using System.ComponentModel.DataAnnotations.Schema; | ||
| using System.Reflection; | ||
| using Newtonsoft.Json; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.Persistence | ||
| { | ||
| internal class EFCoreSagaLogData : ISagaLogData | ||
| { | ||
| public int LogId { get; set; } | ||
| public string SagaId { get; set; } | ||
| [NotMapped] | ||
| public SagaId Id => SagaId; | ||
| public string SagaType { get; set; } | ||
| public long CreatedAt { get; set; } | ||
| [NotMapped] | ||
| public object Message => JsonConvert.DeserializeObject(MessagePayload); | ||
| public string MessagePayload { get; set; } | ||
|
|
||
| Type ISagaLogData.Type => Assembly.GetEntryAssembly()?.GetType(SagaType); | ||
|
|
||
| public EFCoreSagaLogData(string sagaId, string sagaType, long createdAt, string messagePayload) | ||
| { | ||
| SagaId = sagaId; | ||
| SagaType = sagaType; | ||
| CreatedAt = createdAt; | ||
| MessagePayload = messagePayload; | ||
| } | ||
| } | ||
| } |
37 changes: 37 additions & 0 deletions
37
src/Chronicle.Integrations.EFCore/Persistence/EFCoreSagaState.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Newtonsoft.Json; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.Persistence | ||
| { | ||
| internal class EFCoreSagaState<TContext> : ISagaStateRepository where TContext : DbContext | ||
| { | ||
| private readonly TContext _dbContext; | ||
|
|
||
| public EFCoreSagaState(TContext dbContext) | ||
| { | ||
| _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); | ||
| } | ||
|
|
||
| public async Task<ISagaState> ReadAsync(SagaId id, Type type) | ||
| => await _dbContext.Set<EFCoreSagaStateData>() | ||
| .FirstOrDefaultAsync(sld => sld.SagaId == id.Id && sld.SagaType == type.FullName); | ||
|
|
||
| public async Task WriteAsync(ISagaState state) | ||
UmerIftikhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| var entity = await _dbContext | ||
| .Set<EFCoreSagaStateData>() | ||
| .FirstOrDefaultAsync(sld => sld.SagaId == state.Id.Id && sld.SagaType == state.Type.ToString()); | ||
| if (entity is {}) | ||
| { | ||
| _dbContext.Set<EFCoreSagaStateData>().Remove(entity); | ||
| } | ||
|
|
||
| await _dbContext.Set<EFCoreSagaStateData>().AddAsync( | ||
| new EFCoreSagaStateData(state.Id.Id, state.Type.ToString(), state.State, JsonConvert.SerializeObject(state.Data)) | ||
| ); | ||
| await _dbContext.SaveChangesAsync(); | ||
| } | ||
| } | ||
| } | ||
54 changes: 54 additions & 0 deletions
54
src/Chronicle.Integrations.EFCore/Persistence/EFCoreSagaStateData.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| using System; | ||
| using Newtonsoft.Json; | ||
| using System.ComponentModel.DataAnnotations.Schema; | ||
| using System.Reflection; | ||
| using System.Linq; | ||
|
|
||
| namespace Chronicle.Integrations.EFCore.Persistence | ||
| { | ||
| internal class EFCoreSagaStateData : ISagaState | ||
| { | ||
| public string SagaId { get; set; } | ||
| [NotMapped] | ||
| public SagaId Id => SagaId.ToString(); | ||
|
|
||
| public string SagaType { get; set; } | ||
| [NotMapped] | ||
| Type ISagaState.Type => Assembly.GetEntryAssembly()?.GetType(SagaType); | ||
UmerIftikhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| public SagaStates State { get; private set; } | ||
|
|
||
| // public object Data => JsonConvert.DeserializeObject(MessagePayload); | ||
| public object Data | ||
| { | ||
| get | ||
| { | ||
| var currType = Assembly.GetEntryAssembly()?.GetType(SagaType); | ||
UmerIftikhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| var sagaInterface = currType.GetInterfaces() | ||
| .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ISaga<>)); | ||
| var sagaGenericDataType = sagaInterface?.GetGenericArguments()?.FirstOrDefault(); | ||
| var currPayLoad = JsonConvert.DeserializeObject(MessagePayload, sagaGenericDataType); | ||
| return currPayLoad; | ||
| } | ||
| } | ||
|
|
||
| public string MessagePayload { get; set; } | ||
|
|
||
| public Type DataType { get; } | ||
|
|
||
| public EFCoreSagaStateData(string sagaId, string sagaType, SagaStates state, string messagePayload) | ||
| { | ||
| SagaId = sagaId; | ||
| SagaType = sagaType; | ||
| State = state; | ||
| MessagePayload = messagePayload; | ||
| } | ||
|
|
||
| public void Update(SagaStates state, object data = null) | ||
| { | ||
| State = state; | ||
| MessagePayload = JsonConvert.SerializeObject(data); | ||
| } | ||
|
|
||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.