Example #1
0
        public IOutput Create()
        {
            var group = new FileGroup("Aggregates");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Aggregates");
            sb.Al("{");
            sb.I(1).Al("public abstract class Aggregate: Aggregate<Guid>, IAggregate");
            sb.I(1).Al("{ }");
            sb.B();
            sb.I(1).Al("public abstract class Aggregate<T>: IAggregate<T> where T : notnull");
            sb.I(1).Al("{");
            sb.B();
            sb.I(2).Al("public T Id { get; protected set; } = default!;");
            sb.B();
            sb.I(2).Al("public int Version { get; protected set; }");
            sb.B();
            sb.I(2).Al("[NonSerialized] private readonly Queue<IEvent> uncommittedEvents = new Queue<IEvent>();");
            sb.B();
            sb.I(2).Al("public virtual void When(object @event) { }");
            sb.B();
            sb.I(2).Al("public IEvent[] DequeueUncommittedEvents()");
            sb.I(2).Al("{");
            sb.I(3).Al("var dequeuedEvents = uncommittedEvents.ToArray();");
            sb.B();
            sb.I(3).Al("uncommittedEvents.Clear();");
            sb.B();
            sb.I(3).Al("return dequeuedEvents;");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("protected void Enqueue(IEvent @event)");
            sb.I(2).Al("{");
            sb.I(3).Al("uncommittedEvents.Enqueue(@event);");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("Aggregate.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Aggregates");
            sb.Al("{");
            sb.I(1).Al("public interface IAggregate: IAggregate<Guid>");
            sb.B();
            sb.I(1).Al("{ }");
            sb.B();
            sb.I(1).Al("public interface IAggregate<out T>: IProjection");
            sb.I(1).Al("{");
            sb.I(2).Al("T Id { get; }");
            sb.I(2).Al("int Version { get; }");
            sb.B();
            sb.I(2).Al("IEvent[] DequeueUncommittedEvents();");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("IAggregate.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #2
0
        public IOutput Create()
        {
            var group = new FileGroup("Ids");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Ids");
            sb.Al("{");
            sb.I(1).Al("public interface IIdGenerator");
            sb.I(1).Al("{");
            sb.I(2).Al("Guid New();");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("IIdGenerator.cs", sb.ToString(), canOverwrite: true));

            sb.Clear();
            sb.Al($"namespace {_module.Namespace}.Core.Ids");
            sb.Al("{");
            sb.I(1).Al("public class NulloIdGenerator : IIdGenerator");
            sb.I(1).Al("{");
            sb.I(2).Al("public Guid New() => Guid.NewGuid();");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("NulloIdGenerator.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #3
0
        public IOutput Create()
        {
            var group = new FileGroup("Queries");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public interface IQuery<out TResponse>: IRequest<TResponse>");
            sb.I(1).Al("{ }");
            sb.Al("}");

            group.AddFile(new File("IQuery.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public interface IQueryBus");
            sb.I(1).Al("{");
            sb.I(2).Al("Task<TResponse> Send<TQuery, TResponse>(TQuery query) where TQuery : IQuery<TResponse>;");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("IQueryBus.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public interface IQueryHandler<in TQuery, TResponse>: IRequestHandler<TQuery, TResponse>");
            sb.I(2).Al("where TQuery : IQuery<TResponse>");
            sb.I(1).Al("{");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("IQueryHandler.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public class QueryBus: IQueryBus");
            sb.I(1).Al("{");
            sb.I(2).Al("private readonly IMediator _mediator;");
            sb.B();
            sb.I(2).Al("public QueryBus(IMediator mediator)");
            sb.I(2).Al("{");
            sb.I(3).Al("_mediator = mediator;");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public Task<TResponse> Send<TQuery, TResponse>(TQuery query) where TQuery : IQuery<TResponse>");
            sb.I(2).Al("{");
            sb.I(3).Al("return _mediator.Send(query);");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("QueryBus.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #4
0
        public IOutput Create()
        {
            var group = new FileGroup("Commands");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Commands");
            sb.Al("{");
            sb.I(1).Al("public interface ICommand: IRequest { }");
            sb.Al("}");

            group.AddFile(new File("ICommand.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Commands");
            sb.Al("{");
            sb.I(1).Al("public interface ICommandBus");
            sb.I(1).Al("{");
            sb.I(2).Al("Task Send<TCommand>(TCommand command) where TCommand : ICommand;");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("ICommandBus.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Commands");
            sb.Al("{");
            sb.I(1).Al("public interface ICommandHandler<in T>: IRequestHandler<T>");
            sb.I(2).Al("where T : ICommand");
            sb.I(1).Al("{");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("ICommandHandler.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Commands");
            sb.Al("{");
            sb.I(1).Al("public class CommandBus: ICommandBus");
            sb.I(1).Al("{");
            sb.I(2).Al("private readonly IMediator _mediator;");
            sb.B();
            sb.I(2).Al("public CommandBus(IMediator mediator)");
            sb.I(2).Al("{");
            sb.I(3).Al("_mediator = mediator;");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public Task Send<TCommand>(TCommand command) where TCommand : ICommand");
            sb.I(2).Al("{");
            sb.I(3).Al("return _mediator.Send(command);");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("CommandBus.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #5
0
        public IOutput Create()
        {
            var files = new FileGroup();

            if (_model is null)
            {
                _module.Models.ForEach(m => m.Behaviours.ForEach(b => files.AddFile((IFile) new BehaviourRequestGenerator(Settings, _module, m, b).Create())));
            }
            else
            {
                _model.Behaviours.ForEach(b => files.AddFile((IFile) new BehaviourRequestGenerator(Settings, _module, _model, b).Create()));
            }
            return(files);
        }
Example #6
0
        public IOutput Create()
        {
            var group = new FileGroup("Extensions");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Extensions");
            sb.Al("{");
            sb.I(1).Al("public static class ListExtensions");
            sb.I(1).Al("{");
            sb.I(2).Al("public static IList<T> Replace<T>(this IList<T> list, T existingElement, T replacement)");
            sb.I(2).Al("{");
            sb.I(3).Al("var indexOfExistingItem = list.IndexOf(existingElement);");
            sb.I(3).Al("if (indexOfExistingItem == -1)");
            sb.I(4).Al("throw new ArgumentOutOfRangeException(nameof(existingElement), \"Element was not found\");");
            sb.B();
            sb.I(3).Al("list[indexOfExistingItem] = replacement;");
            sb.B();
            sb.I(3).Al("return list;");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("ListExtensions.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #7
0
        public IOutput Create()
        {
            var projectName = _module.Namespace + ".Common";
            var project     = (IProject) new Project(projectName)
            {
                Path = System.IO.Path.Combine("src", projectName)
            };

            var files = new FileGroup();

            project.AddFileGroup(files);

            var sb = new StringBuilder();

            sb.Al("<Project Sdk=\"Microsoft.NET.Sdk\">");
            sb.B();
            sb.I(1).Al("<PropertyGroup>");
            sb.I(2).Al("<TargetFramework>net5.0</TargetFramework>");
            sb.I(2).Al($"<RootNamespace>{project.Name}</RootNamespace>");
            sb.I(2).Al("<LangVersion>Preview</LangVersion>");
            sb.I(2).Al($"<Nullable>enable</Nullable>");
            sb.I(1).Al("</PropertyGroup>");
            sb.B();
            sb.I(1).Al("<ItemGroup>");
            sb.I(2).Al($"<PackageReference Include=\"CSharpFunctionalExtensions\" Version=\"{Settings.Packages.GetVersion("CSharpFunctionalExtensions", "2.17.0")}\" />");
            sb.I(1).Al("</ItemGroup>");
            sb.B();
            sb.Al("</Project>");

            var projectFile = new File(project.Name + ".csproj", sb.ToString());

            files.AddFile(projectFile);

            return(project);
        }
Example #8
0
        public IOutput Create()
        {
            var files = new FileGroup();

            if (_model == null)
            {
                _module.Models.ForEach(a => files.AddFile((IFile) new ConfigGenerated(Settings, _module, a).Create()));
                _module.Models.ForEach(a => files.AddFile((IFile) new ModelGenerated(Settings, _module, a).Create()));
            }
            else
            {
                files.AddFile((IFile) new ConfigGenerated(Settings, _module, _model).Create());
                files.AddFile((IFile) new ModelGenerated(Settings, _module, _model).Create());
            }
            return(files);
        }
Example #9
0
        public IOutput Create()
        {
            var group = new FileGroup("Responses");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Responses");
            sb.Al("{");
            sb.I(1).Al("public class PagedListResponse<T>");
            sb.I(1).Al("{");
            sb.I(2).Al("public IReadOnlyList<T> Items { get; }");
            sb.I(2).Al("public long TotalItemCount { get; }");
            sb.I(2).Al("public bool HasNextPage { get; }");
            sb.I(2).Al("public PagedListResponse(IEnumerable<T> items, long totalItemCount, bool hasNextPage)");
            sb.I(2).Al("{");
            sb.I(3).Al("Items = items.ToList();");
            sb.I(3).Al("TotalItemCount = totalItemCount;");
            sb.I(3).Al("HasNextPage = hasNextPage;");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("PagedListResponse.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #10
0
        public IOutput Create()
        {
            var fileGroup = new FileGroup();

            foreach (var behaviour in _model.Behaviours)
            {
                if (!string.IsNullOrWhiteSpace(behaviour.Event))
                {
                    var sb = new StringBuilder();

                    sb.Al($"namespace {_module.Namespace}.Common.Domain.Events");
                    sb.Al("{");
                    sb.I(1).Al($"public class {behaviour.Event} : BaseDomainEvent<{_model.Name}, Guid>");
                    sb.I(1).Al("{");
                    sb.I(2).Al("/// <summary>");
                    sb.I(2).Al("/// for deserialization");
                    sb.I(2).Al("/// </summary>");
                    sb.I(2).Al($"private {behaviour.Event}() {{ }}");
                    sb.B();
                    sb.I(2).Al($"public {behaviour.Event}({_model.Name} {_model.Name.Singular.LocalVariable}) : base({_model.Name.Singular.LocalVariable})");
                    sb.I(2).Al("{");
                    sb.I(3).Al("// todo: ");
                    sb.I(2).Al("}");
                    sb.I(1).Al("}");
                    sb.Al("}");

                    fileGroup.AddFile(new File(behaviour.Event + ".cs", sb.ToString(), path: "Events"));
                }
            }

            return(fileGroup);
        }
        public IOutput Create()
        {
            var group = new FileGroup("Repositories");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Repositories");
            sb.Al("{");
            sb.I(1).Al("public interface IRepository<T> where T : IAggregate");
            sb.I(1).Al("{");
            sb.I(2).Al("Task<T?> Find(Guid id, CancellationToken cancellationToken);");
            sb.I(2).Al("Task Add(T aggregate, CancellationToken cancellationToken);");
            sb.I(2).Al("Task Update(T aggregate, CancellationToken cancellationToken);");
            sb.I(2).Al("Task Delete(T aggregate, CancellationToken cancellationToken);");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("IRepository.cs", sb.ToString(), canOverwrite: true));

            sb.Clear();
            sb.Al($"namespace {_module.Namespace}.Core.Ids");
            sb.Al("{");
            sb.I(1).Al("public static class RepositoryExtensions");
            sb.I(1).Al("{");
            sb.I(2).Al("public static async Task<T> Get<T>(this IRepository<T> repository, Guid id, CancellationToken cancellationToken = default) where T : IAggregate");
            sb.I(2).Al("{");
            sb.I(3).Al("var entity = await repository.Find(id, cancellationToken);");
            sb.B();
            sb.I(3).Al("return entity ?? throw AggregateNotFoundException.For<T>(id);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public static async Task<Unit> GetAndUpdate<T>(this IRepository<T> repository, Guid id, Action<T> action, CancellationToken cancellationToken = default) where T : IAggregate");
            sb.I(2).Al("{");
            sb.I(3).Al("var entity = await repository.Get<T>(id, cancellationToken);");
            sb.I(3).Al("action(entity);");
            sb.I(3).Al("await repository.Update(entity, cancellationToken);");
            sb.B();
            sb.I(3).Al("return Unit.Value;");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("RepositoryExtensions.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #12
0
        public IOutput Create()
        {
            var group = new FileGroup("Subscriptions");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Subscriptions");
            sb.Al("{");
            sb.I(1).Al("public class InMemorySubscriptionCheckpointRepository: ISubscriptionCheckpointRepository");
            sb.I(1).Al("{");
            sb.I(2).Al("private readonly ConcurrentDictionary<string, ulong> checkpoints = new();");
            sb.B();
            sb.I(2).Al("public ValueTask<ulong?> Load(string subscriptionId, CancellationToken ct)");
            sb.I(2).Al("{");
            sb.I(3).Al("return new(checkpoints.TryGetValue(subscriptionId, out var checkpoint) ? checkpoint : null);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public ValueTask Store(string subscriptionId, ulong position, CancellationToken ct)");
            sb.I(2).Al("{");
            sb.I(3).Al("checkpoints.AddOrUpdate(subscriptionId, position,(_, _) => position);");
            sb.I(3).Al("return ValueTask.CompletedTask;");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("InMemorySubscriptionCheckpointRepository.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Subscriptions");
            sb.Al("{");
            sb.I(1).Al("public interface ISubscriptionCheckpointRepository");
            sb.I(1).Al("{");
            sb.I(2).Al("ValueTask<ulong?> Load(string subscriptionId, CancellationToken ct);");
            sb.B();
            sb.I(2).Al("ValueTask Store(string subscriptionId, ulong position, CancellationToken ct);");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("ISubscriptionCheckpointRepository.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #13
0
        public IOutput Create()
        {
            var group = new FileGroup("Requests");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Requests");
            sb.Al("{");
            sb.I(1).Al("public interface IExternalCommandBus");
            sb.I(1).Al("{");
            sb.I(2).Al("Task Post<T>(string url, string path, T command, CancellationToken cancellationToken = default) where T: ICommand;");
            sb.I(2).Al("Task Put<T>(string url, string path, T command, CancellationToken cancellationToken = default) where T: ICommand;");
            sb.I(2).Al("Task Delete<T>(string url, string path, T command, CancellationToken cancellationToken = default) where T: ICommand;");
            sb.I(1).Al("}");
            sb.B();
            sb.I(1).Al("public class ExternalCommandBus: IExternalCommandBus");
            sb.I(1).Al("{");
            sb.I(2).Al("public Task Post<T>(string url, string path, T command, CancellationToken cancellationToken = default) where T: ICommand");
            sb.I(2).Al("{");
            sb.I(3).Al("var client = new RestClient(url);");
            sb.B();
            sb.I(3).Al("var request = new RestRequest(path, DataFormat.Json);");
            sb.I(3).Al("request.AddJsonBody(command);");
            sb.B();
            sb.I(3).Al("return client.PostAsync<dynamic>(request, cancellationToken);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public Task Put<T>(string url, string path, T command, CancellationToken cancellationToken = default) where T: ICommand");
            sb.I(2).Al("{");
            sb.I(3).Al("var client = new RestClient(url);");
            sb.B();
            sb.I(3).Al("var request = new RestRequest(path, DataFormat.Json);");
            sb.I(3).Al("request.AddJsonBody(command);");
            sb.B();
            sb.I(3).Al("return client.PutAsync<dynamic>(request, cancellationToken);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public Task Delete<T>(string url, string path, T command, CancellationToken cancellationToken = default) where T: ICommand");
            sb.I(2).Al("{");
            sb.I(3).Al("var client = new RestClient(url);");
            sb.B();
            sb.I(3).Al("var request = new RestRequest(path, DataFormat.Json);");
            sb.I(3).Al("request.AddJsonBody(command);");
            sb.B();
            sb.I(3).Al("return client.DeleteAsync<dynamic>(request, cancellationToken);");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("ExternalCommandBus.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
        public IOutput Create()
        {
            var group = new FileGroup("Projections");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Projections");
            sb.Al("{");
            sb.I(1).Al("public interface IProjection");
            sb.I(1).Al("{");
            sb.I(2).Al("void When(object @event);");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("IProjection.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #15
0
        public IOutput Create()
        {
            var projectName = _module.Namespace + ".DataAccess";
            var project     = (IProject) new Project(projectName)
            {
                Path = System.IO.Path.Combine("src", projectName)
            };

            var files = new FileGroup();

            project.AddFileGroup(files);

            var sb = new StringBuilder();

            sb.Al("<Project Sdk=\"Microsoft.NET.Sdk\">");
            sb.B();
            sb.I(1).Al("<PropertyGroup>");
            sb.I(2).Al("<TargetFramework>net5.0</TargetFramework>");
            sb.I(2).Al("<Configurations>Debug;Release;DebugOnPremise;DebugAzure</Configurations>");
            sb.I(2).Al($"<RootNamespace>{project.Name}</RootNamespace>");
            sb.I(2).Al("<LangVersion>Preview</LangVersion>");
            sb.I(2).Al($"<Nullable>enable</Nullable>");
            sb.I(1).Al("</PropertyGroup>");
            sb.B();
            sb.I(1).Al("<ItemGroup>");
            sb.I(2).Al($"<PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"{Settings.Packages.GetVersion("Microsoft.EntityFrameworkCore.Design", "5.0.7")}\">");
            sb.I(3).Al($"<PrivateAssets>all</PrivateAssets>");
            sb.I(3).Al($"<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>");
            sb.I(2).Al($"</PackageReference>");
            sb.I(2).Al($"<PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"{Settings.Packages.GetVersion("Microsoft.EntityFrameworkCore.SqlServer", "5.0.7")}\" />");
            sb.I(2).Al($"<PackageReference Include=\"Swashbuckle.AspNetCore\" Version=\"{Settings.Packages.GetVersion("Swashbuckle.AspNetCore", "6.1.4")}\" />");
            sb.I(1).Al("</ItemGroup>");
            sb.B();
            sb.I(1).Al("<ItemGroup>");
            sb.I(2).Al($"<ProjectReference Include=\"..\\{_module.Company}.{_module.Project}.Common\\{_module.Company}.{_module.Project}.Common.csproj\" />");
            sb.I(1).Al("</ItemGroup>");
            sb.B();
            sb.Al("</Project>");

            var projectFile = new File(project.Name + ".csproj", sb.ToString());

            files.AddFile(projectFile);

            return(project);
        }
Example #16
0
        public IOutput Create()
        {
            var projectName = _module.Namespace + ".Application";
            var project     = (IProject) new Project(projectName)
            {
                Path = System.IO.Path.Combine("src", projectName)
            };

            var files = new FileGroup();

            project.AddFileGroup(files);

            var sb = new StringBuilder();

            sb.Al("<Project Sdk=\"Microsoft.NET.Sdk.Web\">");
            sb.B();
            sb.I(1).Al("<PropertyGroup>");
            sb.I(2).Al("<TargetFramework>net5.0</TargetFramework>");
            sb.I(2).Al($"<RootNamespace>{project.Name}</RootNamespace>");
            sb.I(2).Al("<LangVersion>Preview</LangVersion>");
            sb.I(2).Al($"<Nullable>enable</Nullable>");
            sb.I(1).Al("</PropertyGroup>");
            sb.B();
            sb.I(1).Al("<ItemGroup>");
            sb.I(2).Al($"<PackageReference Include=\"FluentValidation.AspNetCore\" Version=\"{Settings.Packages.GetVersion("FluentValidation.AspNetCore", "10.2.3")}\" />");
            sb.I(2).Al($"<PackageReference Include=\"MediatR.Extensions.Microsoft.DependencyInjection\" Version=\"{Settings.Packages.GetVersion("MediatR.Extensions.Microsoft.DependencyInjection", "9.0.0")}\" />");
            sb.I(2).Al($"<PackageReference Include=\"Swashbuckle.AspNetCore\" Version=\"{Settings.Packages.GetVersion("Swashbuckle.AspNetCore", "6.1.4")}\" />");
            sb.I(1).Al("</ItemGroup>");
            sb.B();
            sb.I(1).Al("<ItemGroup>");
            sb.I(2).Al($"<ProjectReference Include=\"..\\{_module.Company}.{_module.Project}.BusinessLogic\\{_module.Company}.{_module.Project}.BusinessLogic.csproj\" />");
            sb.I(2).Al($"<ProjectReference Include=\"..\\{_module.Company}.{_module.Project}.Common\\{_module.Company}.{_module.Project}.Common.csproj\" />");
            sb.I(1).Al("</ItemGroup>");
            sb.B();
            sb.Al("</Project>");

            var projectFile = new File(project.Name + ".csproj", sb.ToString());

            files.AddFile(projectFile);

            return(project);
        }
Example #17
0
        public IOutput Create()
        {
            var projectName = _module.Namespace + ".Core";
            var project     = (IProject) new Project(projectName)
            {
                Path = System.IO.Path.Combine("src", projectName)
            };

            var files = new FileGroup();

            project.AddFileGroup(files);

            var sb = new StringBuilder();

            sb.Al("<Project Sdk=\"Microsoft.NET.Sdk\">");
            sb.B();
            sb.I(1).Al("<PropertyGroup>");
            sb.I(2).Al("<TargetFramework>net5.0</TargetFramework>");
            sb.I(2).Al($"<RootNamespace>{project.Name}</RootNamespace>");
            sb.I(2).Al("<LangVersion>Preview</LangVersion>");
            sb.I(2).Al("<Nullable>enable</Nullable>");
            sb.I(2).Al("<TreatWarningsAsErrors>true</TreatWarningsAsErrors>");
            sb.I(1).Al("</PropertyGroup>");
            sb.B();
            sb.I(1).Al("<ItemGroup>");
            sb.I(2).Al($"<PackageReference Include=\"FluentAssertions\" Version=\"{Settings.Packages.GetVersion("FluentAssertions", "5.10.3")}\" />");
            sb.I(2).Al($"<PackageReference Include=\"MediatR\" Version=\"{Settings.Packages.GetVersion("MediatR", "9.0.0")}\" />");
            sb.I(2).Al($"<PackageReference Include=\"Microsoft.Extensions.DependencyInjection.Abstractions\" Version=\"{Settings.Packages.GetVersion("Microsoft.Extensions.DependencyInjection.Abstractions", "5.0.0")}\" />");
            sb.I(2).Al($"<PackageReference Include=\"RestSharp\" Version=\"{Settings.Packages.GetVersion("RestSharp", "106.11.7")}\" />");
            sb.I(1).Al("</ItemGroup>");
            sb.B();
            sb.Al("</Project>");

            var projectFile = new File(project.Name + ".csproj", sb.ToString());

            files.AddFile(projectFile);

            return(project);
        }
Example #18
0
        public IOutput Create()
        {
            var group = new FileGroup("Reflections");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Reflections");
            sb.Al("{");
            sb.I(1).Al("public static class TypeProvider");
            sb.I(1).Al("{");
            sb.I(2).Al("public static Type? GetTypeFromAnyReferencingAssembly(string typeName)");
            sb.I(2).Al("{");
            sb.I(3).Al("var referencedAssemblies = System.Reflection.Assembly.GetEntryAssembly()?");
            sb.I(4).Al(".GetReferencedAssemblies()");
            sb.I(4).Al(".Select(a => a.FullName);");
            sb.B();
            sb.I(3).Al("if (referencedAssemblies == null)");
            sb.I(4).Al("return null;");
            sb.B();
            sb.I(3).Al("return AppDomain.CurrentDomain.GetAssemblies()");
            sb.I(4).Al(".Where(a => referencedAssemblies.Contains(a.FullName))");
            sb.I(4).Al(".SelectMany(a => a.GetTypes().Where(x => x.FullName == typeName || x.Name == typeName))");
            sb.I(4).Al(".FirstOrDefault();");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public static Type? GetFirstMatchingTypeFromCurrentDomainAssembly(string typeName)");
            sb.I(2).Al("{");
            sb.I(3).Al("return AppDomain.CurrentDomain.GetAssemblies()");
            sb.I(4).Al(".SelectMany(a => a.GetTypes().Where(x => x.FullName == typeName || x.Name == typeName))");
            sb.I(4).Al(".FirstOrDefault();");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("TypeProvider.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #19
0
        public IOutput Create()
        {
            var group = new FileGroup("Exceptions");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Exceptions");
            sb.Al("{");
            sb.I(1).Al("public class AggregateNotFoundException : Exception");
            sb.I(1).Al("{");
            sb.I(2).Al("public AggregateNotFoundException(string typeName, Guid id): base($\"{typeName} with id '{id}' was not found\")");
            sb.I(2).Al("{ }");
            sb.B();
            sb.I(2).Al("public static AggregateNotFoundException For<T>(Guid id)");
            sb.I(2).Al("{");
            sb.I(3).Al("return new AggregateNotFoundException(typeof(T).Name, id);");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("AggregateNotFoundException.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #20
0
        public IOutput Create()
        {
            var group = new FileGroup("Threading");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Threading");
            sb.Al("{");
            sb.I(1).Al("public static class NoSynchronizationContextScope");
            sb.I(1).Al("{");
            sb.I(2).Al("public static Disposable Enter()");

            sb.I(2).Al("{");
            sb.I(3).Al("var context = SynchronizationContext.Current;");
            sb.I(3).Al("SynchronizationContext.SetSynchronizationContext(null);");
            sb.I(3).Al("return new Disposable(context);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public struct Disposable: IDisposable");
            sb.I(2).Al("{");
            sb.I(3).Al("private readonly SynchronizationContext? _synchronizationContext;");
            sb.B();
            sb.I(3).Al("public Disposable(SynchronizationContext? synchronizationContext)");
            sb.I(3).Al("{");
            sb.I(4).Al("_synchronizationContext = synchronizationContext;");
            sb.I(3).Al("}");
            sb.B();
            sb.I(3).Al("public void Dispose() =>");
            sb.I(4).Al("SynchronizationContext.SetSynchronizationContext(_synchronizationContext);");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("NoSynchronizationContextScope.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #21
0
        public IOutput Create()
        {
            var project = (IProject) new ProjectFile(Settings, _module).Create();

            project.FileGroups.First().AddFile((IFile) new EntityFile(Settings, _module).Create());
            project.FileGroups.First().AddFile((IFile) new EnumValueObjectFile(Settings, _module).Create());
            project.FileGroups.First().AddFile((IFile) new SimpleValueObjectFile(Settings, _module).Create());
            project.FileGroups.First().AddFile((IFile) new ValueObjectFile(Settings, _module).Create());
            project.FileGroups.First().AddFile((IFile) new ErrorFile(Settings, _module).Create());
            project.FileGroups.First().AddFile((IFile) new NestingFile(Settings).Create());
            project.FileGroups.First().AddFile((IFile) new UsingsFile(Settings, _module).Create());
            project.FileGroups.First().AddFile((IFile) new EmailSampleFile(Settings, _module).Create());
            project.AddFileGroup((IFileGroup) new DomainClass.Generator(Settings, _module, null).Create());

            var enums = new FileGroup("Enums");

            _module.Enumerations.ForEach(e => enums.AddFile((IFile) new EnumClass.Generator(Settings, _module, e).Create()));
            if (enums.Files.Any())
            {
                project.AddFileGroup(enums);
            }

            return(project);
        }
Example #22
0
        public IOutput Create()
        {
            var group = new FileGroup("Events");

            var sb = new StringBuilder();

            sb.Al($"namespace {_module.Namespace}.Core.Events.External");
            sb.Al("{");
            sb.I(1).Al("public interface IExternalEventProducer");
            sb.I(1).Al("{");
            sb.I(2).Al("Task Publish(IExternalEvent @event);");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("IExternalEventProducer.cs", sb.ToString(), path: "External", canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Events.External");
            sb.Al("{");
            sb.I(1).Al("public interface IExternalEventConsumer");
            sb.I(1).Al("{");
            sb.I(2).Al("Task StartAsync(CancellationToken cancellationToken);");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("IExternalEventConsumer.cs", sb.ToString(), path: "External", canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Events.External");
            sb.Al("{");
            sb.I(1).Al("public class NulloExternalEventProducer : IExternalEventProducer");
            sb.I(1).Al("{");
            sb.I(2).Al("public Task Publish(IExternalEvent @event)");
            sb.I(2).Al("{");
            sb.I(3).Al("return Task.CompletedTask;");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("NulloExternalEventProducer.cs", sb.ToString(), path: "External", canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Events");
            sb.Al("{");
            sb.I(1).Al("public interface IEvent: INotification");
            sb.I(1).Al("{ }");
            sb.Al("}");

            group.AddFile(new File("IEvent.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Events");
            sb.Al("{");
            sb.I(1).Al("public interface IExternalEvent: IEvent");
            sb.I(1).Al("{ }");
            sb.Al("}");

            group.AddFile(new File("IExternalEvent.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public interface IEventBus");
            sb.I(1).Al("{");
            sb.I(2).Al("Task Publish(params IEvent[] events);");
            sb.I(1).Al("}");
            sb.Al("}");

            group.AddFile(new File("IEventBus.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public interface IEventHandler<in TEvent>: INotificationHandler<TEvent>");
            sb.I(2).Al("where TEvent : IEvent");
            sb.I(1).Al("{");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("IEventHandler.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public class EventBus: IEventBus");
            sb.I(1).Al("{");
            sb.I(2).Al("private readonly IMediator _mediator;");
            sb.I(2).Al("private readonly IExternalEventProducer _externalEventProducer;");
            sb.B();
            sb.I(2).Al("public EventBus(IMediator mediator, IExternalEventProducer externalEventProducer)");
            sb.I(2).Al("{");
            sb.I(3).Al("_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));");
            sb.I(3).Al("_externalEventProducer = externalEventProducer ?? throw new ArgumentNullException(nameof(externalEventProducer));");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public async Task Publish(params IEvent[] events)");
            sb.I(2).Al("{");
            sb.I(3).Al("foreach (var @event in events)");
            sb.I(3).Al("{");
            sb.I(4).Al("await _mediator.Publish(@event);");
            sb.I(4).Al("if (@event is IExternalEvent externalEvent)");
            sb.I(5).Al("await _externalEventProducer.Publish(externalEvent);");
            sb.I(3).Al("}");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("EventBus.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public class EventTypeMapper");
            sb.I(1).Al("{");
            sb.I(2).Al("private static readonly EventTypeMapper Instance = new();");
            sb.B();
            sb.I(2).Al("private readonly ConcurrentDictionary<Type, string> TypeNameMap = new();");
            sb.I(2).Al("private readonly ConcurrentDictionary<string, Type> TypeMap = new();");
            sb.B();
            sb.I(2).Al("public static void AddCustomMap<T>(string mappedEventTypeName) => AddCustomMap(typeof(T), mappedEventTypeName);");
            sb.B();
            sb.I(2).Al("public static void AddCustomMap(Type eventType, string mappedEventTypeName)");
            sb.I(2).Al("{");
            sb.I(3).Al("Instance.TypeNameMap.AddOrUpdate(eventType, mappedEventTypeName, (_, _) => mappedEventTypeName);");
            sb.I(3).Al("Instance.TypeMap.AddOrUpdate(mappedEventTypeName, eventType, (_, _) => eventType);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public static string ToName<TEventType>() => ToName(typeof(TEventType));");
            sb.B();
            sb.I(2).Al("public static string ToName(Type eventType) => Instance.TypeNameMap.GetOrAdd(eventType, (_) =>");
            sb.I(2).Al("{");
            sb.I(3).Al("var eventTypeName = eventType.FullName!.Replace(\".\", \"_\");");
            sb.B();
            sb.I(3).Al("Instance.TypeMap.AddOrUpdate(eventTypeName, eventType, (_, _) => eventType);");
            sb.B();
            sb.I(3).Al("return eventTypeName;");
            sb.I(2).Al("});");
            sb.B();
            sb.I(2).Al("public static Type ToType(string eventTypeName) => Instance.TypeMap.GetOrAdd(eventTypeName, (_) =>");
            sb.I(2).Al("{");
            sb.I(3).Al("var type = TypeProvider.GetFirstMatchingTypeFromCurrentDomainAssembly(eventTypeName.Replace(\"_\", \".\"))!;");
            sb.B();
            sb.I(3).Al("if (type == null)");
            sb.I(4).Al("throw new Exception($\"Type map for '{eventTypeName}' wasn't found!\");");
            sb.B();
            sb.I(3).Al("Instance.TypeNameMap.AddOrUpdate(type, eventTypeName, (_, _) => eventTypeName);");
            sb.B();
            sb.I(3).Al("return type;");
            sb.I(2).Al("});");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("EventTypeMapper.cs", sb.ToString(), canOverwrite: true));
            sb.Clear();

            sb.Al($"namespace {_module.Namespace}.Core.Queries");
            sb.Al("{");
            sb.I(1).Al("public class StreamNameMapper");
            sb.I(1).Al("{");
            sb.I(2).Al("private static readonly StreamNameMapper Instance = new();");
            sb.B();
            sb.I(2).Al("private readonly ConcurrentDictionary<Type, string> TypeNameMap = new();");
            sb.B();
            sb.I(2).Al("public static void AddCustomMap<TStream>(string mappedStreamName) =>");
            sb.I(3).Al("AddCustomMap(typeof(TStream), mappedStreamName);");
            sb.B();
            sb.I(2).Al("public static void AddCustomMap(Type streamType, string mappedStreamName)");
            sb.I(2).Al("{");
            sb.I(3).Al("Instance.TypeNameMap.AddOrUpdate(streamType, mappedStreamName, (_, _) => mappedStreamName);");
            sb.I(2).Al("}");
            sb.B();
            sb.I(2).Al("public static string ToStreamPrefix<TStream>() => ToStreamPrefix(typeof(TStream));");
            sb.B();
            sb.I(2).Al("public static string ToStreamPrefix(Type streamType) => Instance.TypeNameMap.GetOrAdd(streamType, (_) =>");
            sb.I(2).Al("{");
            sb.I(3).Al("var modulePrefix = streamType.Namespace!.Split(\".\").First();");
            sb.I(3).Al("return $\"{modulePrefix}_{streamType.Name}\";");
            sb.I(2).Al("});");
            sb.B();
            sb.I(2).Al("public static string ToStreamId<TStream>(object aggregateId, object? tenantId = null) =>");
            sb.I(3).Al("ToStreamId(typeof(TStream), aggregateId);");
            sb.B();
            sb.I(2).Al("public static string ToStreamId(Type streamType, object aggregateId, object? tenantId = null)");
            sb.I(2).Al("{");
            sb.I(3).Al("var tenantPrefix = tenantId != null ? $\"{tenantId}_\"  : \"\";");
            sb.B();
            sb.I(3).Al("return $\"{tenantPrefix}{ToStreamPrefix(streamType)}-{aggregateId}\";");
            sb.I(2).Al("}");
            sb.I(1).Al("}");
            sb.Al("}");
            group.AddFile(new File("StreamNameMapper.cs", sb.ToString(), canOverwrite: true));

            return(group);
        }
Example #23
0
 private void AddModelFiles(FileGroup files, Model model)
 {
     files.AddFile((IFile) new DomainUser(Settings, _module, model).Create());
     files.AddFile((IFile) new DomainGenerated(Settings, _module, model).Create());
 }