diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..ac3e23a --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "name": "Java", + "image": "mcr.microsoft.com/devcontainers/java:1-21", + "features": { + "ghcr.io/devcontainers/features/java:1": { + "version": "none", + "installMaven": "true", + "mavenVersion": "3.8.6", + "installGradle": "true" + } + } +} \ No newline at end of file diff --git a/.github/workflows/junie.yml b/.github/workflows/junie.yml new file mode 100644 index 0000000..9860e79 --- /dev/null +++ b/.github/workflows/junie.yml @@ -0,0 +1,21 @@ +name: Junie +run-name: Junie run ${{ inputs.run_id }} + +permissions: + contents: write + +on: + workflow_dispatch: + inputs: + run_id: + description: "id of workflow process" + required: true + workflow_params: + description: "stringified params" + required: true + +jobs: + call-workflow-passing-data: + uses: jetbrains-junie/junie-workflows/.github/workflows/ej-issue.yml@main + with: + workflow_params: ${{ inputs.workflow_params }} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoNSubstitutingRegistrationSource.cs b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoNSubstitutingRegistrationSource.cs deleted file mode 100644 index 141065f..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoNSubstitutingRegistrationSource.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using Autofac.Builder; -using Autofac.Core; - -using NSubstitute.Core; - -namespace DependencyInjectionCourse.Tests.Conventions -{ - public class AutoNSubstitutingRegistrationSource : IRegistrationSource - { - private readonly ISubstituteFactory _substituteFactory; - - public AutoNSubstitutingRegistrationSource() - { - _substituteFactory = SubstitutionContext.Current.SubstituteFactory; - } - - public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) - { - var swt = service as IServiceWithType; - if (swt == null) - { - yield break; - } - - IEnumerable existingReg = registrationAccessor(service); - if (existingReg.Any()) - { - yield break; - } - - IComponentRegistration reg = RegistrationBuilder.ForDelegate((c, p) => - { - object fakeInstance = _substituteFactory.Create(new Type[] { swt.ServiceType }, null); - return fakeInstance; - }).As(swt.ServiceType) - .SingleInstance() - .CreateRegistration(); - - yield return reg; - } - - public bool IsAdapterForIndividualComponents { get; } - } -} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.csproj b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.csproj deleted file mode 100644 index bd43d9f..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.csproj +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - Debug - AnyCPU - {11C33D6E-DC39-41EB-A6FF-E4CA754EB15A} - Library - Properties - DependencyInjectionCourse.Tests - DependencyInjectionCourse.Tests - v4.6.2 - 512 - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Autofac.4.1.1\lib\net45\Autofac.dll - True - - - ..\packages\AutofacContrib.NSubstitute.4.0.1\lib\NET45\AutofacContrib.NSubstitute.dll - True - - - ..\packages\Chill.2.4.3\lib\net45\Chill.dll - True - - - ..\packages\FluentAssertions.4.19.0\lib\net45\FluentAssertions.dll - True - - - ..\packages\FluentAssertions.4.19.0\lib\net45\FluentAssertions.Core.dll - True - - - ..\packages\NSubstitute.1.10.0.0\lib\net45\NSubstitute.dll - True - - - ..\packages\AutoFixture.3.50.2\lib\net40\Ploeh.AutoFixture.dll - True - - - ..\packages\AutoFixture.AutoNSubstitute.3.50.2\lib\net40\Ploeh.AutoFixture.AutoNSubstitute.dll - True - - - ..\packages\AutoFixture.Xunit2.3.50.2\lib\net45\Ploeh.AutoFixture.Xunit2.dll - True - - - - - - - - - - - ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - True - - - ..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll - True - - - ..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll - True - - - ..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll - True - - - - - - - - - - - - - - - - - - - - - - - {9DB19A34-0D4C-4F7A-9F4D-2E54C15E1634} - DependencyInjectionCourse - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer.cs b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer.cs deleted file mode 100644 index e9b785f..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Autofac; - -using DependencyInjectionCourse.Cache; -using DependencyInjectionCourse.ExternalDependencies; -using DependencyInjectionCourse.Order; -using DependencyInjectionCourse.Tests.Conventions; - -using FluentAssertions; - -using NSubstitute; - -using Xunit; - -namespace DependencyInjectionCourse.Tests -{ - /// - /// Auto-Mocking container aspect - /// - /// - public class OrderService_Tests_With_DependencyInection_And_AutoSubstitutingContainer : TestBaseWithAutoSubstitutingIoc - { - [Fact] - public void with_dependency_injection_and_automocking_container() - { - //----------------------------------------------------------------------------------------------------------- - // Arrange - //----------------------------------------------------------------------------------------------------------- - Building(builder => { builder.RegisterType().As(); }); - - AFake().Get("1").Returns(new Basket(1, 50)); - - var sut = Use(); - - //----------------------------------------------------------------------------------------------------------- - // Act - //----------------------------------------------------------------------------------------------------------- - OrderResult result = sut.DoOrder(1); - - //----------------------------------------------------------------------------------------------------------- - // Assert - //----------------------------------------------------------------------------------------------------------- - result.BasketId.Should().Be(1); - result.Total.Should().Be(50); - AFake().Received().Salute(); - } - } -} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoSubstituteIoc.cs b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoSubstituteIoc.cs deleted file mode 100644 index 4bc4002..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoSubstituteIoc.cs +++ /dev/null @@ -1,24 +0,0 @@ -using AutofacContrib.NSubstitute; - -namespace DependencyInjectionCourse.Tests -{ - public abstract class TestBaseWithAutoSubstituteIoc - { - protected AutoSubstitute AutoSubstitute; - - protected TestBaseWithAutoSubstituteIoc() - { - AutoSubstitute = new AutoSubstitute(); - } - - protected T AFake() - { - return AutoSubstitute.Resolve(); - } - - protected TService Use() - { - return AutoSubstitute.Provide(); - } - } -} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoSubstitutingIoc.cs b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoSubstitutingIoc.cs deleted file mode 100644 index ba38a4b..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoSubstitutingIoc.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; - -using Autofac; -using Autofac.Features.ResolveAnything; - -using DependencyInjectionCourse.Tests.Conventions; - -namespace DependencyInjectionCourse.Tests -{ - public abstract class TestBaseWithAutoSubstitutingIoc - { - protected ContainerBuilder Builder; - protected IContainer Resolver; - - protected TestBaseWithAutoSubstitutingIoc() - { - Builder = new ContainerBuilder(); - Builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); - Builder.RegisterSource(new AutoNSubstitutingRegistrationSource()); - } - - protected void Building(Action builderAction) - { - builderAction(Builder); - Resolver = Builder.Build(); - } - - protected T AFake() - { - return Resolver.Resolve(); - } - - protected T Use() - { - return Resolver.Resolve(); - } - } -} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/app.config b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/app.config deleted file mode 100644 index d6c4695..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/app.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/packages.config b/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/packages.config deleted file mode 100644 index ee356f4..0000000 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/packages.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index e3fcc2d..c8d927c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ # Samples -#### 1 - Quartz integration with castle windsor, convention based and modular ioc -#### 2 - Hangfire Samples -#### 3 - Aspect Oriented RequestObject(DTO) Validation in WCF Services with FluentValidation and CastleWindsor, Domain Driven Design +My presentation samples and playgrounds diff --git a/SampleAbpApplication/src/SampleAbpApplication/project.json b/SampleAbpApplication/src/SampleAbpApplication/project.json deleted file mode 100644 index 54ff7fd..0000000 --- a/SampleAbpApplication/src/SampleAbpApplication/project.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "1.0.0-*", - "buildOptions": { - "emitEntryPoint": true - }, - - "dependencies": { - "Abp": "1.2.2", - "Abp.EntityFramework": "1.2.2", - "EntityFrameworkProfiler.Appender": "3.0.3105" - }, - - "frameworks": { - "net452": { - - } - } -} diff --git a/blog/2020/CliApiProject/CliApi.Tests/ApiTestBase.cs b/blog/2020/CliApiProject/CliApi.Tests/ApiTestBase.cs new file mode 100644 index 0000000..fb98091 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi.Tests/ApiTestBase.cs @@ -0,0 +1,36 @@ +namespace CliApi.Tests +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Microsoft.AspNetCore.Mvc.Testing; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + + public abstract class ApiTestBase : WebApplicationFactory + where TEntryPoint : class + { + protected Dictionary Configuration { get; set; } + + protected Action ConfigureServicesForTest { get; set; } + + protected override IHostBuilder CreateHostBuilder() + { + IHostBuilder builder = base.CreateHostBuilder(); + builder.ConfigureServices(collection => + { + //Configure test services + ConfigureServicesForTest?.Invoke(collection); + }); + builder.ConfigureAppConfiguration((context, configBuilder) => + { + if (Configuration != null && Configuration.Any()) + { + configBuilder.AddInMemoryCollection(Configuration); + } + }); + return builder; + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi.Tests/ApiTests.cs b/blog/2020/CliApiProject/CliApi.Tests/ApiTests.cs new file mode 100644 index 0000000..8405136 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi.Tests/ApiTests.cs @@ -0,0 +1,24 @@ +namespace CliApi.Tests +{ + using System.Net; + using System.Net.Http; + using System.Threading.Tasks; + using Xunit; + + public class ApiTests : ApiTestBase + { + private readonly HttpClient _client; + + public ApiTests() + { + _client = CreateClient(); + } + + [Fact] + public async Task Can_Get_From_Any_Url() + { + HttpResponseMessage response = await _client.GetAsync(string.Empty); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi.Tests/CliApi.Tests.csproj b/blog/2020/CliApiProject/CliApi.Tests/CliApi.Tests.csproj new file mode 100644 index 0000000..cbf2542 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi.Tests/CliApi.Tests.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + + + diff --git a/blog/2020/CliApiProject/CliApi.Tests/CliTestBase.cs b/blog/2020/CliApiProject/CliApi.Tests/CliTestBase.cs new file mode 100644 index 0000000..25658aa --- /dev/null +++ b/blog/2020/CliApiProject/CliApi.Tests/CliTestBase.cs @@ -0,0 +1,60 @@ +namespace CliApi.Tests +{ + using System.Collections.Generic; + using System.CommandLine; + using System.CommandLine.Builder; + using System.CommandLine.IO; + using System.CommandLine.Parsing; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Xunit.Abstractions; + + public abstract class CliTestBase : ApplicationFactory + { + private readonly ITestOutputHelper _testOutputHelper; + + protected CliTestBase(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + + protected TestConsole Console { get; } = new TestConsole(); + protected string ConsoleStdOut => Console.Out.ToString(); + protected string ConsoleErrorOut => Console.Error.ToString(); + protected Dictionary Configuration { get; set; } = new Dictionary(); + + public override CommandLineBuilder CreateCommandLineBuilder(string[] args) + { + CommandLineBuilder cliBuilder = base.CreateCommandLineBuilder(args); + ConfigureServices += services => + { + services.AddSingleton(Console); + }; + ConfigureAppConfiguration += builder => + { + if (Configuration != null && Configuration.Any()) builder.AddInMemoryCollection(Configuration); + }; + return cliBuilder.ConfigureConsole(context => Console); + } + + protected async Task Execute(params string[] args) + { + int returnValue = await CreateCommandLineBuilder(args).Build().InvokeAsync(args); + if (!string.IsNullOrEmpty(ConsoleStdOut)) + { + _testOutputHelper.WriteLine("-----CLI STD OUT-----"); + _testOutputHelper.WriteLine($"{ConsoleStdOut}"); + } + + if (!string.IsNullOrEmpty(ConsoleErrorOut)) + { + _testOutputHelper.WriteLine("-----CLI ERROR-----"); + _testOutputHelper.WriteLine($"{ConsoleErrorOut}"); + } + + return returnValue; + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi.Tests/CliTests.cs b/blog/2020/CliApiProject/CliApi.Tests/CliTests.cs new file mode 100644 index 0000000..0dea701 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi.Tests/CliTests.cs @@ -0,0 +1,63 @@ +namespace CliApi.Tests +{ + using System.Threading.Tasks; + using Xunit; + using Xunit.Abstractions; + using CommandHandling.Handlers; + using CommandHandling.Handlers.Dependencies; + using FakeItEasy; + using Microsoft.Extensions.DependencyInjection; + + public class CliTests : CliTestBase + { + public CliTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + } + + [Fact] + public async Task Can_Execute_DbInitCommandLineHandler() + { + int exitCode = await Execute("db", "init"); + + Assert.Equal(0, exitCode); + Assert.Contains($"{nameof(DbInitCommandLineHandler)} was executed successfully", + ConsoleStdOut); + } + + [Fact] + public async Task Can_Execute_MigrateToLatestVersionCommandLineHandler() + { + int exitCode = await Execute("db", "migrate"); + + Assert.Equal(0, exitCode); + Assert.Contains( + $"{nameof(MigrateToLatestVersionCommandHandler)} was executed successfully", + ConsoleStdOut); + Assert.Contains( + "Cloud", + ConsoleStdOut); + } + + [Fact] + public async Task Can_Execute_MigrationStrategy_With_Something_From_Test_Context() + { + const string migrationStrategy = "test"; + var fakeMigrationStrategy = A.Fake(); + A.CallTo(() => fakeMigrationStrategy.Get()).Returns(migrationStrategy); + ConfigureServices += services => + { + services.AddTransient(sp => fakeMigrationStrategy); + }; + + int exitCode = await Execute("db", "migrate"); + + Assert.Equal(0, exitCode); + Assert.Contains( + $"{nameof(MigrateToLatestVersionCommandHandler)} was executed successfully", + ConsoleStdOut); + Assert.Contains( + migrationStrategy, + ConsoleStdOut); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi.sln b/blog/2020/CliApiProject/CliApi.sln new file mode 100644 index 0000000..f61df3a --- /dev/null +++ b/blog/2020/CliApiProject/CliApi.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliApi", "CliApi\CliApi.csproj", "{B2C3821D-1C41-424C-8B5E-2B92F06DA19D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliApi.Tests", "CliApi.Tests\CliApi.Tests.csproj", "{DA76030D-525E-45D8-8F8B-8C014D1230D4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2C3821D-1C41-424C-8B5E-2B92F06DA19D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2C3821D-1C41-424C-8B5E-2B92F06DA19D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2C3821D-1C41-424C-8B5E-2B92F06DA19D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2C3821D-1C41-424C-8B5E-2B92F06DA19D}.Release|Any CPU.Build.0 = Release|Any CPU + {DA76030D-525E-45D8-8F8B-8C014D1230D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA76030D-525E-45D8-8F8B-8C014D1230D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA76030D-525E-45D8-8F8B-8C014D1230D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA76030D-525E-45D8-8F8B-8C014D1230D4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchsolution b/blog/2020/CliApiProject/CliApi.v3.ncrunchsolution similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchsolution rename to blog/2020/CliApiProject/CliApi.v3.ncrunchsolution diff --git a/blog/2020/CliApiProject/CliApi/ApplicationFactory.cs b/blog/2020/CliApiProject/CliApi/ApplicationFactory.cs new file mode 100644 index 0000000..a796a50 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/ApplicationFactory.cs @@ -0,0 +1,69 @@ +namespace CliApi +{ + using System; + using System.CommandLine; + using System.CommandLine.Builder; + using System.CommandLine.Hosting; + using System.CommandLine.IO; + using CommandHandling; + using CommandHandling.Handlers.Dependencies; + using Microsoft.AspNetCore.Hosting; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + + /// + /// Responsible with creation of Application's building blocks + /// WebHost and Cli Host + /// + public class ApplicationFactory + { + /// + /// Provides an extensibility to register dependencies for CLI Integration or Unit testing + /// + protected Action ConfigureServices { get; set; } = services => { }; + + /// + /// Provides an extensibility to for CLI Integration or Unit testing + /// + protected Action ConfigureAppConfiguration { get; set; } = config => { }; + + /// + /// .NetCore Web API entrance for Main. + /// Creates the HostBuilder to be executed in Main. + /// + /// + /// + public virtual IHostBuilder CreateWebHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } + + /// + /// Builds the command-line pipeline + /// + /// + public virtual CommandLineBuilder CreateCommandLineBuilder(string[] args) + { + return new CommandLineBuilder( + new RootCommand().CreateCommandHandling() + ) + .UseHost(host => + host.ConfigureServices(services => + { + services.AddSingleton(); + services.AddTransient(); + services.AddCommandLineHandlers(); + ConfigureServices(services); + }) + .ConfigureAppConfiguration(builder => + { + builder.AddCommandLine(args); + ConfigureAppConfiguration(builder); + }) + ) + .BranchToWebIfNoCommandToExecute(); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CliApi.csproj b/blog/2020/CliApiProject/CliApi/CliApi.csproj new file mode 100644 index 0000000..f2ca1d0 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CliApi.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp3.1 + + + + + + + + diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/CommandLineExtensions.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/CommandLineExtensions.cs new file mode 100644 index 0000000..b659d16 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/CommandLineExtensions.cs @@ -0,0 +1,193 @@ +namespace CliApi.CommandHandling +{ + using System; + using System.Collections.Generic; + using System.CommandLine; + using System.CommandLine.Builder; + using System.CommandLine.Invocation; + using System.CommandLine.IO; + using System.CommandLine.Parsing; + using System.Linq; + using System.Threading.Tasks; + using Handlers; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using Microsoft.Extensions.Logging; + + /// + /// Command handling extensions + /// + public static class CommandExtensions + { + /// + /// Makes easier the addressing handlers to the commands and also enables dependency injection as default. + /// + /// + /// + /// + public static Command HandledBy(this Command command) where T : ICommandHandler + { + command.Handler = CommandHandler.Create((host, invocation) => + { + var logger = host.Services.GetService>(); + if (command is ValidatedCommand toBeValidated) + { + (bool isValid, string reason) = toBeValidated.Validate(host.Services); + if (!isValid) + { + invocation.Console.Error.WriteLine(reason); + logger.LogError(reason); + invocation.ResultCode = (int) ExitCode.Error; + return Task.FromResult(ExitCode.Error); + } + } + + if (invocation.HasErrors()) + { + invocation.PrintErrors(); + return Task.FromResult(ExitCode.Error); + } + + return host.Services.GetRequiredService().InvokeAsync(invocation); + }); + + return command; + } + + /// + /// Adds the given command and returns the command itself + /// + /// + /// + /// + public static Command AddSubCommand(this Command command, Command subCommand) + { + command.AddCommand(subCommand); + return command; + } + + /// + /// Configures the command and returns the instance. + /// + /// + /// + /// + public static Command Configure(this Command command, Action configure) + { + configure(command); + return command; + } + + /// + /// Configures the command and returns the instance. + /// + /// + /// + /// + public static Command Configure(this ValidatedCommand command, Action configure) + { + configure(command); + return command; + } + + /// + /// Configures command handling pipeline by adding a middleware, if incoming command is not handled by the pipeline, + /// in other words if it is not known then the pipeline passes through these args to the application entry point. + /// + /// + /// + public static CommandLineBuilder BranchToWebIfNoCommandToExecute(this CommandLineBuilder builder) + { + bool IsKnownCommand(IEnumerable tokens) => tokens.All(x => x.Type == TokenType.Command); + builder.UseMiddleware(async (context, next) => + { + IReadOnlyList tokens = context.ParseResult.Tokens; + if (IsKnownCommand(tokens)) + { + await next(context); + } + else + { + context.ResultCode = ExitCode.BranchToWeb; + } + }); + return builder; + } + + /// + /// Adds application's command handlers + /// + /// + /// + public static IServiceCollection AddCommandLineHandlers(this IServiceCollection services) + { + services.AddTransient(); + services.AddTransient(); + return services; + } + + /// + /// Creates command line handling and appends handlers to the provided + /// + /// + /// + /// + public static Command CreateCommandHandling(this RootCommand root) + { + Command version = new Command("version") + .Configure(c => { c.AddAlias("--version"); }) + .HandledBy(); + + Command db = new Command("db") + .Configure(c => { c.AddAlias("--db"); }) + .AddSubCommand(new ValidatedCommand("init") + .Configure(c => + { + c.AddAlias("--init"); + c.AddAlias("-i"); + c.AddValidation(sp => { return (true, string.Empty); }); + }) + .HandledBy()) + .AddSubCommand(new ValidatedCommand("migrate") + .Configure(c => + { + c.AddAlias("--migrate"); + c.AddAlias("-m"); + c.AddValidation(sp => { return (true, string.Empty); }); + }) + .HandledBy()); + + Command rootCommand = root + .AddSubCommand(db) + .AddSubCommand(version); + + return rootCommand; + } + + /// + /// Prints parse errors to the console + /// + /// + public static void PrintErrors(this InvocationContext context) + { + if (!context.HasErrors()) + { + return; + } + + foreach (ParseError error in context.ParseResult.Errors) + { + context.Console.Error.WriteLine(error.Message); + } + } + + /// + /// Returns true if there is any parsing error + /// + /// + public static bool HasErrors(this InvocationContext context) + { + return context.ParseResult.Errors.Any(); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/ExitCode.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/ExitCode.cs new file mode 100644 index 0000000..881bd25 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/ExitCode.cs @@ -0,0 +1,9 @@ +namespace CliApi.CommandHandling +{ + public static class ExitCode + { + public const int Error = -1; + public const int Ok = 0; + public const int BranchToWeb = 1; + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/DbInitCommandLineHandler.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/DbInitCommandLineHandler.cs new file mode 100644 index 0000000..87ede0a --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/DbInitCommandLineHandler.cs @@ -0,0 +1,14 @@ +namespace CliApi.CommandHandling.Handlers +{ + using System.CommandLine.Invocation; + using System.Threading.Tasks; + + public class DbInitCommandLineHandler : ICommandHandler + { + public Task InvokeAsync(InvocationContext context) + { + context.Console.Out.Write($"{nameof(DbInitCommandLineHandler)} was executed successfully!"); + return Task.FromResult(ExitCode.Ok); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/Dependencies/CloudMigrationStrategy.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/Dependencies/CloudMigrationStrategy.cs new file mode 100644 index 0000000..1300597 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/Dependencies/CloudMigrationStrategy.cs @@ -0,0 +1,15 @@ +namespace CliApi.CommandHandling.Handlers.Dependencies +{ + public interface IMigrationStrategy + { + string Get(); + } + + public class CloudMigrationStrategy : IMigrationStrategy + { + public string Get() + { + return "Cloud"; + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/GetVersionCommandLineHandler.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/GetVersionCommandLineHandler.cs new file mode 100644 index 0000000..4e72ce2 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/GetVersionCommandLineHandler.cs @@ -0,0 +1,14 @@ +namespace CliApi.CommandHandling.Handlers +{ + using System.CommandLine.Invocation; + using System.Threading.Tasks; + + public class GetVersionCommandLineHandler: ICommandHandler + { + public Task InvokeAsync(InvocationContext context) + { + context.Console.Out.Write(GetType().Assembly.ImageRuntimeVersion); + return Task.FromResult(ExitCode.Ok); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/MigrateToLatestVersionCommandLineHandler.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/MigrateToLatestVersionCommandLineHandler.cs new file mode 100644 index 0000000..2d9f77b --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/Handlers/MigrateToLatestVersionCommandLineHandler.cs @@ -0,0 +1,32 @@ +namespace CliApi.CommandHandling.Handlers +{ + using System.CommandLine.Invocation; + using System.CommandLine.IO; + using System.Threading.Tasks; + using Dependencies; + using Microsoft.Extensions.Logging; + + public class MigrateToLatestVersionCommandHandler : ICommandHandler + { + private readonly IMigrationStrategy _migrationStrategy; + private readonly ILogger _logger; + + public MigrateToLatestVersionCommandHandler( + IMigrationStrategy migrationStrategy, + ILogger logger) + { + _migrationStrategy = migrationStrategy; + _logger = logger; + } + + public Task InvokeAsync(InvocationContext context) + { + string strategy = _migrationStrategy.Get(); + context.Console.Out.WriteLine($"The selected migration strategy:{strategy}"); + _logger.LogInformation("Migration Strategy: {strategy}", strategy); + context.Console.Out.Write($"{nameof(MigrateToLatestVersionCommandHandler)} was executed successfully!"); + + return Task.FromResult(ExitCode.Ok); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/CommandHandling/ValidatedCommand.cs b/blog/2020/CliApiProject/CliApi/CommandHandling/ValidatedCommand.cs new file mode 100644 index 0000000..1f4b8f3 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/CommandHandling/ValidatedCommand.cs @@ -0,0 +1,48 @@ +namespace CliApi.CommandHandling +{ + using System; + using System.Collections.Generic; + using System.CommandLine; + + /// + /// Creates a set of validation logic around + /// + public class ValidatedCommand : Command + { + private readonly List> _validations; + + public ValidatedCommand(string name, string description = null) : base(name, description) + { + _validations = new List>(); + } + + /// + /// Adds a validation callback before the command gets executed, + /// also has runtime IServiceProvider to resolve required services during the validation + /// + /// + public void AddValidation(Func callback) + { + _validations.Add(callback); + } + + /// + /// Executes the command validations and returns outcome. Stops after first validation error encounter. + /// + /// + /// + public (bool, string) Validate(IServiceProvider provider) + { + foreach (Func validation in _validations) + { + (bool isValid, string reason) = validation(provider); + if (!isValid) + { + return (false, reason); + } + } + + return (true, string.Empty); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/Program.cs b/blog/2020/CliApiProject/CliApi/Program.cs new file mode 100644 index 0000000..f7520f7 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/Program.cs @@ -0,0 +1,38 @@ +namespace CliApi +{ + using System.CommandLine.Parsing; + using System.Threading; + using System.Threading.Tasks; + using CommandHandling; + using Microsoft.Extensions.Hosting; + + public static class Program + { + public static async Task Main(string[] args) + { + var factory = new ApplicationFactory(); + int exitCode = await factory + .CreateCommandLineBuilder(args) + .Build() + .InvokeAsync(args); + + if (exitCode != ExitCode.BranchToWeb) + return exitCode; + + await CreateHostBuilder(args).Build().RunAsync(CancellationToken.None); + return ExitCode.Ok; + } + + /// + /// We keep this builder to test the Application's Web Entry from the proper place + /// where we actually use with normal flow + /// + /// + /// + private static IHostBuilder CreateHostBuilder(string[] args) + { + var factory = new ApplicationFactory(); + return factory.CreateWebHostBuilder(args); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/CliApi/Properties/launchSettings.json b/blog/2020/CliApiProject/CliApi/Properties/launchSettings.json new file mode 100644 index 0000000..63e3520 --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:20675", + "sslPort": 44364 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "WebApplication": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/blog/2020/CliApiProject/CliApi/Startup.cs b/blog/2020/CliApiProject/CliApi/Startup.cs new file mode 100644 index 0000000..f90332d --- /dev/null +++ b/blog/2020/CliApiProject/CliApi/Startup.cs @@ -0,0 +1,33 @@ +namespace CliApi +{ + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.Http; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", async context => + { + await context.Response.WriteAsync("Hello World!"); + }); + }); + } + } +} \ No newline at end of file diff --git a/blog/2020/CliApiProject/readme.md b/blog/2020/CliApiProject/readme.md new file mode 100644 index 0000000..81bf44a --- /dev/null +++ b/blog/2020/CliApiProject/readme.md @@ -0,0 +1 @@ +https://www.oguzhansoykan.com/posts/2020/2020-04-15-netcore-cli/ diff --git a/AODtoValidation/AODtoValidation.sln b/dotnet/AODtoValidation/AODtoValidation.sln similarity index 100% rename from AODtoValidation/AODtoValidation.sln rename to dotnet/AODtoValidation/AODtoValidation.sln diff --git a/AODtoValidation/AODtoValidation/AODtoValidation.csproj b/dotnet/AODtoValidation/AODtoValidation/AODtoValidation.csproj similarity index 100% rename from AODtoValidation/AODtoValidation/AODtoValidation.csproj rename to dotnet/AODtoValidation/AODtoValidation/AODtoValidation.csproj diff --git a/AODtoValidation/AODtoValidation/App.config b/dotnet/AODtoValidation/AODtoValidation/App.config similarity index 100% rename from AODtoValidation/AODtoValidation/App.config rename to dotnet/AODtoValidation/AODtoValidation/App.config diff --git a/AODtoValidation/AODtoValidation/Bootstrapper.cs b/dotnet/AODtoValidation/AODtoValidation/Bootstrapper.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Bootstrapper.cs rename to dotnet/AODtoValidation/AODtoValidation/Bootstrapper.cs diff --git a/AODtoValidation/AODtoValidation/Dtos/CashOrderRequest.cs b/dotnet/AODtoValidation/AODtoValidation/Dtos/CashOrderRequest.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Dtos/CashOrderRequest.cs rename to dotnet/AODtoValidation/AODtoValidation/Dtos/CashOrderRequest.cs diff --git a/AODtoValidation/AODtoValidation/Dtos/CashOrderResponse.cs b/dotnet/AODtoValidation/AODtoValidation/Dtos/CashOrderResponse.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Dtos/CashOrderResponse.cs rename to dotnet/AODtoValidation/AODtoValidation/Dtos/CashOrderResponse.cs diff --git a/AODtoValidation/AODtoValidation/Dtos/RequestBase.cs b/dotnet/AODtoValidation/AODtoValidation/Dtos/RequestBase.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Dtos/RequestBase.cs rename to dotnet/AODtoValidation/AODtoValidation/Dtos/RequestBase.cs diff --git a/AODtoValidation/AODtoValidation/Dtos/ResponseBase.cs b/dotnet/AODtoValidation/AODtoValidation/Dtos/ResponseBase.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Dtos/ResponseBase.cs rename to dotnet/AODtoValidation/AODtoValidation/Dtos/ResponseBase.cs diff --git a/AODtoValidation/AODtoValidation/Installers/InterceptorInstaller.cs b/dotnet/AODtoValidation/AODtoValidation/Installers/InterceptorInstaller.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Installers/InterceptorInstaller.cs rename to dotnet/AODtoValidation/AODtoValidation/Installers/InterceptorInstaller.cs diff --git a/AODtoValidation/AODtoValidation/Installers/MobileServiceInstaller.cs b/dotnet/AODtoValidation/AODtoValidation/Installers/MobileServiceInstaller.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Installers/MobileServiceInstaller.cs rename to dotnet/AODtoValidation/AODtoValidation/Installers/MobileServiceInstaller.cs diff --git a/AODtoValidation/AODtoValidation/Installers/ValidatorInstaller.cs b/dotnet/AODtoValidation/AODtoValidation/Installers/ValidatorInstaller.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Installers/ValidatorInstaller.cs rename to dotnet/AODtoValidation/AODtoValidation/Installers/ValidatorInstaller.cs diff --git a/AODtoValidation/AODtoValidation/Interceptor/ValidatorInterceptor.cs b/dotnet/AODtoValidation/AODtoValidation/Interceptor/ValidatorInterceptor.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Interceptor/ValidatorInterceptor.cs rename to dotnet/AODtoValidation/AODtoValidation/Interceptor/ValidatorInterceptor.cs diff --git a/AODtoValidation/AODtoValidation/Program.cs b/dotnet/AODtoValidation/AODtoValidation/Program.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Program.cs rename to dotnet/AODtoValidation/AODtoValidation/Program.cs diff --git a/AODtoValidation/AODtoValidation/Properties/AssemblyInfo.cs b/dotnet/AODtoValidation/AODtoValidation/Properties/AssemblyInfo.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Properties/AssemblyInfo.cs rename to dotnet/AODtoValidation/AODtoValidation/Properties/AssemblyInfo.cs diff --git a/AODtoValidation/AODtoValidation/SelfInstaller.cs b/dotnet/AODtoValidation/AODtoValidation/SelfInstaller.cs similarity index 100% rename from AODtoValidation/AODtoValidation/SelfInstaller.cs rename to dotnet/AODtoValidation/AODtoValidation/SelfInstaller.cs diff --git a/AODtoValidation/AODtoValidation/Service/IMobileService.cs b/dotnet/AODtoValidation/AODtoValidation/Service/IMobileService.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Service/IMobileService.cs rename to dotnet/AODtoValidation/AODtoValidation/Service/IMobileService.cs diff --git a/AODtoValidation/AODtoValidation/Service/MobileService.cs b/dotnet/AODtoValidation/AODtoValidation/Service/MobileService.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Service/MobileService.cs rename to dotnet/AODtoValidation/AODtoValidation/Service/MobileService.cs diff --git a/AODtoValidation/AODtoValidation/Service/ValidateWithRuleAttribute.cs b/dotnet/AODtoValidation/AODtoValidation/Service/ValidateWithRuleAttribute.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Service/ValidateWithRuleAttribute.cs rename to dotnet/AODtoValidation/AODtoValidation/Service/ValidateWithRuleAttribute.cs diff --git a/AODtoValidation/AODtoValidation/Service1.Designer.cs b/dotnet/AODtoValidation/AODtoValidation/Service1.Designer.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Service1.Designer.cs rename to dotnet/AODtoValidation/AODtoValidation/Service1.Designer.cs diff --git a/AODtoValidation/AODtoValidation/Service1.cs b/dotnet/AODtoValidation/AODtoValidation/Service1.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Service1.cs rename to dotnet/AODtoValidation/AODtoValidation/Service1.cs diff --git a/AODtoValidation/AODtoValidation/ServiceStarter.cs b/dotnet/AODtoValidation/AODtoValidation/ServiceStarter.cs similarity index 100% rename from AODtoValidation/AODtoValidation/ServiceStarter.cs rename to dotnet/AODtoValidation/AODtoValidation/ServiceStarter.cs diff --git a/AODtoValidation/AODtoValidation/Validators/CashOrderRequestValidator.cs b/dotnet/AODtoValidation/AODtoValidation/Validators/CashOrderRequestValidator.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Validators/CashOrderRequestValidator.cs rename to dotnet/AODtoValidation/AODtoValidation/Validators/CashOrderRequestValidator.cs diff --git a/AODtoValidation/AODtoValidation/Validators/ValidatorBase.cs b/dotnet/AODtoValidation/AODtoValidation/Validators/ValidatorBase.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Validators/ValidatorBase.cs rename to dotnet/AODtoValidation/AODtoValidation/Validators/ValidatorBase.cs diff --git a/AODtoValidation/AODtoValidation/Validators/ValidatorRuleSet.cs b/dotnet/AODtoValidation/AODtoValidation/Validators/ValidatorRuleSet.cs similarity index 100% rename from AODtoValidation/AODtoValidation/Validators/ValidatorRuleSet.cs rename to dotnet/AODtoValidation/AODtoValidation/Validators/ValidatorRuleSet.cs diff --git a/AODtoValidation/AODtoValidation/packages.config b/dotnet/AODtoValidation/AODtoValidation/packages.config similarity index 100% rename from AODtoValidation/AODtoValidation/packages.config rename to dotnet/AODtoValidation/AODtoValidation/packages.config diff --git a/Abp.Quartz/.cr/Settings.xml b/dotnet/Abp.Quartz/.cr/Settings.xml similarity index 100% rename from Abp.Quartz/.cr/Settings.xml rename to dotnet/Abp.Quartz/.cr/Settings.xml diff --git a/Abp.Quartz/Abp.Quartz.TestConsoleApp/Abp.Quartz.TestConsoleApp.csproj b/dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/Abp.Quartz.TestConsoleApp.csproj similarity index 100% rename from Abp.Quartz/Abp.Quartz.TestConsoleApp/Abp.Quartz.TestConsoleApp.csproj rename to dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/Abp.Quartz.TestConsoleApp.csproj diff --git a/Abp.Quartz/Abp.Quartz.TestConsoleApp/AbpQuartzConsoleAppModule.cs b/dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/AbpQuartzConsoleAppModule.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz.TestConsoleApp/AbpQuartzConsoleAppModule.cs rename to dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/AbpQuartzConsoleAppModule.cs diff --git a/Abp.Quartz/Abp.Quartz.TestConsoleApp/App.config b/dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/App.config similarity index 100% rename from Abp.Quartz/Abp.Quartz.TestConsoleApp/App.config rename to dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/App.config diff --git a/Abp.Quartz/Abp.Quartz.TestConsoleApp/Program.cs b/dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/Program.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz.TestConsoleApp/Program.cs rename to dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/Program.cs diff --git a/Abp.Quartz/Abp.Quartz.TestConsoleApp/Properties/AssemblyInfo.cs b/dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/Properties/AssemblyInfo.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz.TestConsoleApp/Properties/AssemblyInfo.cs rename to dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/Properties/AssemblyInfo.cs diff --git a/Abp.Quartz/Abp.Quartz.TestConsoleApp/packages.config b/dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/packages.config similarity index 100% rename from Abp.Quartz/Abp.Quartz.TestConsoleApp/packages.config rename to dotnet/Abp.Quartz/Abp.Quartz.TestConsoleApp/packages.config diff --git a/Abp.Quartz/Abp.Quartz.sln b/dotnet/Abp.Quartz/Abp.Quartz.sln similarity index 100% rename from Abp.Quartz/Abp.Quartz.sln rename to dotnet/Abp.Quartz/Abp.Quartz.sln diff --git a/Abp.Quartz/Abp.Quartz/Abp.Quartz.csproj b/dotnet/Abp.Quartz/Abp.Quartz/Abp.Quartz.csproj similarity index 100% rename from Abp.Quartz/Abp.Quartz/Abp.Quartz.csproj rename to dotnet/Abp.Quartz/Abp.Quartz/Abp.Quartz.csproj diff --git a/Abp.Quartz/Abp.Quartz/Properties/AssemblyInfo.cs b/dotnet/Abp.Quartz/Abp.Quartz/Properties/AssemblyInfo.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Properties/AssemblyInfo.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Properties/AssemblyInfo.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzJobListener.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzJobListener.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzJobListener.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzJobListener.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzModule.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzModule.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzModule.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzModule.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfigurationExtensions.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfigurationExtensions.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfigurationExtensions.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/Configuration/AbpQuartzConfigurationExtensions.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs diff --git a/Abp.Quartz/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs b/dotnet/Abp.Quartz/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs similarity index 100% rename from Abp.Quartz/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs rename to dotnet/Abp.Quartz/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs diff --git a/Abp.Quartz/Abp.Quartz/packages.config b/dotnet/Abp.Quartz/Abp.Quartz/packages.config similarity index 100% rename from Abp.Quartz/Abp.Quartz/packages.config rename to dotnet/Abp.Quartz/Abp.Quartz/packages.config diff --git a/Abp.Quartz/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj b/dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj similarity index 100% rename from Abp.Quartz/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj rename to dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj diff --git a/Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs b/dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs similarity index 100% rename from Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs rename to dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs diff --git a/Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs b/dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs similarity index 100% rename from Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs rename to dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs diff --git a/Abp.Quartz/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs b/dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs similarity index 100% rename from Abp.Quartz/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs rename to dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs diff --git a/Abp.Quartz/AbpQuartzTask.GoodbyeJob/packages.config b/dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/packages.config similarity index 100% rename from Abp.Quartz/AbpQuartzTask.GoodbyeJob/packages.config rename to dotnet/Abp.Quartz/AbpQuartzTask.GoodbyeJob/packages.config diff --git a/Abp.Quartz/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj b/dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj similarity index 100% rename from Abp.Quartz/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj rename to dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj diff --git a/Abp.Quartz/AbpQuartzTask.HelloJob/HelloJob.cs b/dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/HelloJob.cs similarity index 100% rename from Abp.Quartz/AbpQuartzTask.HelloJob/HelloJob.cs rename to dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/HelloJob.cs diff --git a/Abp.Quartz/AbpQuartzTask.HelloJob/HelloJobModule.cs b/dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/HelloJobModule.cs similarity index 100% rename from Abp.Quartz/AbpQuartzTask.HelloJob/HelloJobModule.cs rename to dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/HelloJobModule.cs diff --git a/Abp.Quartz/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs b/dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs similarity index 100% rename from Abp.Quartz/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs rename to dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs diff --git a/Abp.Quartz/AbpQuartzTask.HelloJob/packages.config b/dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/packages.config similarity index 100% rename from Abp.Quartz/AbpQuartzTask.HelloJob/packages.config rename to dotnet/Abp.Quartz/AbpQuartzTask.HelloJob/packages.config diff --git a/dotnet/DDDCourse/ProductContext.sln b/dotnet/DDDCourse/ProductContext.sln new file mode 100644 index 0000000..fb55b57 --- /dev/null +++ b/dotnet/DDDCourse/ProductContext.sln @@ -0,0 +1,67 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2009 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi", "src\WebApi\WebApi.csproj", "{B093126E-BBED-4D56-88A6-40E05903D7AF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FEAF19C6-6A07-48DF-AD71-68F788F73296}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Solution Items", ".Solution Items", "{CA61B02E-B9DF-4B1E-8840-88B6B3EF700C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{9E6B7863-4795-446D-A6BF-3EBCCAB47573}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00 - Core", "00 - Core", "{9CD8ABC7-A007-4C2E-AA0E-5E2FA237169E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01 - Domain", "01 - Domain", "{DA95A7BD-62CD-4C5F-BDA3-0C5656802866}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02 - Application", "02 - Application", "{B88FD188-E884-4CCE-8DC1-2DFAEB2A5126}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03 - Representation", "03 - Representation", "{6E1BB2AD-A587-4FBE-AFF8-2BE5E8B2D887}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.csproj", "{C8BD5EC7-E084-4A2B-B207-8D522B4A470D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "src\Domain\Domain.csproj", "{538AA792-590A-4431-9960-0E8A2E7FD1FF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "src\Application\Application.csproj", "{30B1E831-9AE7-47DB-BF24-8A0B41779594}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B093126E-BBED-4D56-88A6-40E05903D7AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B093126E-BBED-4D56-88A6-40E05903D7AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B093126E-BBED-4D56-88A6-40E05903D7AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B093126E-BBED-4D56-88A6-40E05903D7AF}.Release|Any CPU.Build.0 = Release|Any CPU + {C8BD5EC7-E084-4A2B-B207-8D522B4A470D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8BD5EC7-E084-4A2B-B207-8D522B4A470D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8BD5EC7-E084-4A2B-B207-8D522B4A470D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8BD5EC7-E084-4A2B-B207-8D522B4A470D}.Release|Any CPU.Build.0 = Release|Any CPU + {538AA792-590A-4431-9960-0E8A2E7FD1FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {538AA792-590A-4431-9960-0E8A2E7FD1FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {538AA792-590A-4431-9960-0E8A2E7FD1FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {538AA792-590A-4431-9960-0E8A2E7FD1FF}.Release|Any CPU.Build.0 = Release|Any CPU + {30B1E831-9AE7-47DB-BF24-8A0B41779594}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30B1E831-9AE7-47DB-BF24-8A0B41779594}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30B1E831-9AE7-47DB-BF24-8A0B41779594}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30B1E831-9AE7-47DB-BF24-8A0B41779594}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {B093126E-BBED-4D56-88A6-40E05903D7AF} = {6E1BB2AD-A587-4FBE-AFF8-2BE5E8B2D887} + {9CD8ABC7-A007-4C2E-AA0E-5E2FA237169E} = {FEAF19C6-6A07-48DF-AD71-68F788F73296} + {DA95A7BD-62CD-4C5F-BDA3-0C5656802866} = {FEAF19C6-6A07-48DF-AD71-68F788F73296} + {B88FD188-E884-4CCE-8DC1-2DFAEB2A5126} = {FEAF19C6-6A07-48DF-AD71-68F788F73296} + {6E1BB2AD-A587-4FBE-AFF8-2BE5E8B2D887} = {FEAF19C6-6A07-48DF-AD71-68F788F73296} + {C8BD5EC7-E084-4A2B-B207-8D522B4A470D} = {9CD8ABC7-A007-4C2E-AA0E-5E2FA237169E} + {538AA792-590A-4431-9960-0E8A2E7FD1FF} = {DA95A7BD-62CD-4C5F-BDA3-0C5656802866} + {30B1E831-9AE7-47DB-BF24-8A0B41779594} = {B88FD188-E884-4CCE-8DC1-2DFAEB2A5126} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {323F4208-BA9A-4C68-8E7B-554F8F92524D} + EndGlobalSection +EndGlobal diff --git a/dotnet/DDDCourse/doc/ddd.pptx b/dotnet/DDDCourse/doc/ddd.pptx new file mode 100644 index 0000000..23480ab Binary files /dev/null and b/dotnet/DDDCourse/doc/ddd.pptx differ diff --git a/dotnet/DDDCourse/src/Application/Application.csproj b/dotnet/DDDCourse/src/Application/Application.csproj new file mode 100644 index 0000000..34fba8a --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Application.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + + + + + + + + + + + + + diff --git a/dotnet/DDDCourse/src/Application/Products/Commands/CreateProductCommand.cs b/dotnet/DDDCourse/src/Application/Products/Commands/CreateProductCommand.cs new file mode 100644 index 0000000..ddf688f --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/Commands/CreateProductCommand.cs @@ -0,0 +1,20 @@ +using System; + +using Core.Bus; + +namespace Products.Commands +{ + public class CreateProductCommand : Command + { + public string Name { get; set; } + + public string Code { get; set; } + + public string Barcode { get; set; } + + public void Validate() + { + if (string.IsNullOrEmpty(Name)) throw new ArgumentNullException(nameof(Name)); + } + } +} diff --git a/dotnet/DDDCourse/src/Application/Products/Dtos/Mapping/MapsterObjectMapper.cs b/dotnet/DDDCourse/src/Application/Products/Dtos/Mapping/MapsterObjectMapper.cs new file mode 100644 index 0000000..9006926 --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/Dtos/Mapping/MapsterObjectMapper.cs @@ -0,0 +1,19 @@ +using Core.ObjectMapper; + +using Mapster; + +namespace Products.Dtos.Mapping +{ + public class MapsterObjectMapper : IObjectMapper + { + public TDestination MapTo(TSource source, TDestination destination) + { + return source.Adapt(destination); + } + + public TDestination MapTo(object source) + { + return source.Adapt(); + } + } +} diff --git a/dotnet/DDDCourse/src/Application/Products/Dtos/ProductDto.cs b/dotnet/DDDCourse/src/Application/Products/Dtos/ProductDto.cs new file mode 100644 index 0000000..d4eda51 --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/Dtos/ProductDto.cs @@ -0,0 +1,11 @@ +namespace Products.Dtos +{ + public class ProductDto + { + public string Name { get; set; } + + public string Barcode { get; set; } + + public string Code { get; set; } + } +} diff --git a/dotnet/DDDCourse/src/Application/Products/ReadModel/IProductReadModel.cs b/dotnet/DDDCourse/src/Application/Products/ReadModel/IProductReadModel.cs new file mode 100644 index 0000000..097d036 --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/ReadModel/IProductReadModel.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +using Products.Dtos; + +namespace Products.ReadModel +{ + public interface IProductReadModel + { + Task> GetAll(); + + Task GetByBarcode(string barcode); + } +} \ No newline at end of file diff --git a/dotnet/DDDCourse/src/Application/Products/ReadModel/ProductReadModel.cs b/dotnet/DDDCourse/src/Application/Products/ReadModel/ProductReadModel.cs new file mode 100644 index 0000000..75103ae --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/ReadModel/ProductReadModel.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +using Core.ObjectMapper; +using Core.Repositories; + +using Products.Dtos; + +namespace Products.ReadModel +{ + public class ProductReadModel : IProductReadModel + { + private readonly IObjectMapper _mapper; + private readonly IRepository _repository; + + public ProductReadModel(IRepository repository, IObjectMapper mapper) + { + _repository = repository; + _mapper = mapper; + } + + public async Task> GetAll() + { + List products = await _repository.GetAll(); + + return _mapper.MapTo>(products); + } + + public async Task GetByBarcode(string barcode) + { + Product product = await _repository.Get(x => x.Barcode == barcode); + + return _mapper.MapTo(product); + } + } +} diff --git a/dotnet/DDDCourse/src/Application/Products/Services/IProductAppService.cs b/dotnet/DDDCourse/src/Application/Products/Services/IProductAppService.cs new file mode 100644 index 0000000..d45337d --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/Services/IProductAppService.cs @@ -0,0 +1,11 @@ +using Core; +using Core.Bus; + +using Products.Commands; + +namespace Products.Services +{ + public interface IProductAppService : IHandles + { + } +} diff --git a/dotnet/DDDCourse/src/Application/Products/Services/ProductAppService.cs b/dotnet/DDDCourse/src/Application/Products/Services/ProductAppService.cs new file mode 100644 index 0000000..56d2729 --- /dev/null +++ b/dotnet/DDDCourse/src/Application/Products/Services/ProductAppService.cs @@ -0,0 +1,57 @@ +using System.Threading.Tasks; +using System.Transactions; + +using Core.Authorization; +using Core.Mailing; +using Core.RealtimeNotifier; +using Core.Session; +using Core.Uow; + +using Products.Commands; + +namespace Products.Services +{ + public class ProductAppService : IProductAppService + { + private readonly IAuthorizationService _authorizationService; + private readonly IProductDomainService _productDomainService; + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly IMailSender _mailSender; + private readonly ISession _session; + private readonly IRealtimeNotifier _realtimeNotifier; + + public ProductAppService( + IProductDomainService productDomainService, + IAuthorizationService authorizationService, + IUnitOfWorkManager unitOfWorkManager, + IMailSender mailSender, + ISession session, + IRealtimeNotifier realtimeNotifier) + { + _productDomainService = productDomainService; + _authorizationService = authorizationService; + _unitOfWorkManager = unitOfWorkManager; + _mailSender = mailSender; + _session = session; + _realtimeNotifier = realtimeNotifier; + } + + public async Task Handle(CreateProductCommand message) + { + _authorizationService.CheckPermission("User.CreateProduct"); + + message.Validate(); + + using (IUnitOfWork unitOfWork = _unitOfWorkManager.Begin(IsolationLevel.ReadCommitted)) + { + await _productDomainService.Create(message.Name, message.Code, message.Barcode); + + await unitOfWork.Complete(); + } + + await _mailSender.Send($"Hello {_session.Username}, product is created for you.", "Product Creation", _session.Email); + + await _realtimeNotifier.Notify("ProductCreated", message.ToString()); + } + } +} diff --git a/dotnet/DDDCourse/src/Core/Core.csproj b/dotnet/DDDCourse/src/Core/Core.csproj new file mode 100644 index 0000000..08b9dab --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + 7.1 + + + + + + + + + diff --git a/dotnet/DDDCourse/src/Core/Core/Aggregates/AggregateRoot.cs b/dotnet/DDDCourse/src/Core/Core/Aggregates/AggregateRoot.cs new file mode 100644 index 0000000..a0b0605 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Aggregates/AggregateRoot.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; + +using Core.Bus; + +namespace Core.Aggregates +{ + public class AggregateRoot + { + protected AggregateRoot() + { + Events = new List(); + } + + private ICollection Events { get; } + + public Guid Id { get; protected set; } + + public override bool Equals(object obj) + { + return Id.Equals(((AggregateRoot)obj).Id); + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + protected void RaiseEvent(Event @event) + { + ApplyChange(@event); + Events.Add(@event); + } + + public ImmutableList GetUncommittedEvents() + { + return Events.ToImmutableList(); + } + + public void MarkEventsAsHandled() + { + Events.Clear(); + } + + protected void ApplyChange(Event @event) + { + ((dynamic)this).Apply(@event); + } + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Authorization/IAuthorizationService.cs b/dotnet/DDDCourse/src/Core/Core/Authorization/IAuthorizationService.cs new file mode 100644 index 0000000..4c560d5 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Authorization/IAuthorizationService.cs @@ -0,0 +1,7 @@ +namespace Core.Authorization +{ + public interface IAuthorizationService + { + bool CheckPermission(string permission); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Bus/IHandles{T}.cs b/dotnet/DDDCourse/src/Core/Core/Bus/IHandles{T}.cs new file mode 100644 index 0000000..15405ef --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Bus/IHandles{T}.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; + +namespace Core.Bus +{ + public interface IHandles + { + Task Handle(T message); + } + + public interface ICommandSender + { + Task Send(T command) where T : Command; + } + + public interface IEventPublisher + { + Task Publish(T @event) where T : Event; + } + + public interface IBus : IEventPublisher, ICommandSender + { + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Bus/IMessage.cs b/dotnet/DDDCourse/src/Core/Core/Bus/IMessage.cs new file mode 100644 index 0000000..295fbb1 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Bus/IMessage.cs @@ -0,0 +1,15 @@ +namespace Core.Bus +{ + public interface IMessage + { + } + + public class Command : IMessage + { + } + + public class Event : IMessage + { + public int Version; + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Bus/InMemoryBus.cs b/dotnet/DDDCourse/src/Core/Core/Bus/InMemoryBus.cs new file mode 100644 index 0000000..47cc190 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Bus/InMemoryBus.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Core.Bus +{ + public class InMemoryBus : IBus + { + private readonly Dictionary>> _routes = new Dictionary>>(); + + public Task Send(T command) where T : Command + { + if (_routes.TryGetValue(typeof(T), out List> handlers)) + { + if (handlers.Count != 1) throw new InvalidOperationException("Command Handler cannot be more than one"); + + handlers.First()(command); + } + else throw new InvalidOperationException("no handler registered"); + + return Task.CompletedTask; + } + + public Task Publish(T @event) where T : Event + { + if (!_routes.TryGetValue(typeof(T), out List> handlers)) return Task.CompletedTask; + + foreach (Action handler in handlers) + { + ThreadPool.QueueUserWorkItem(state => handler(@event)); + } + + return Task.CompletedTask; + } + + public Task Register(Action handler) + { + if (!_routes.TryGetValue(typeof(T), out List> handlers)) + { + handlers = new List>(); + _routes.Add(typeof(T), handlers); + } + + handlers.Add(message => handler((T)message)); + + return Task.CompletedTask; + } + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Entities/Entity.cs b/dotnet/DDDCourse/src/Core/Core/Entities/Entity.cs new file mode 100644 index 0000000..cf401b4 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Entities/Entity.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; + +using Core.Bus; + +namespace Core.Entities +{ + public class Entity + { + private readonly Dictionary> _router; + + public Entity() + { + _router = new Dictionary>(); + } + + public Guid Id { get; protected set; } + + public override bool Equals(object obj) + { + return Id.Equals(((Entity)obj).Id); + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public void Register(Action handler) where TEvent : Event + { + if (!_router.TryGetValue(typeof(TEvent), out Action handle)) + { + _router.Add(typeof(TEvent), @event => handler((TEvent)@event)); + } + } + + public void Route(object @event) + { + if (_router.TryGetValue(@event.GetType(), out Action handler)) + { + handler(@event); + } + } + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Logging/ILogger.cs b/dotnet/DDDCourse/src/Core/Core/Logging/ILogger.cs new file mode 100644 index 0000000..0fe2f5b --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Logging/ILogger.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Core.Logging +{ + public interface ILogger + { + Task Log(string message); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Mailing/IMailSender.cs b/dotnet/DDDCourse/src/Core/Core/Mailing/IMailSender.cs new file mode 100644 index 0000000..af21ab6 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Mailing/IMailSender.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Core.Mailing +{ + public interface IMailSender + { + Task Send(string body, string subject, params string[] to); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/ObjectMapper/IObjectMapper.cs b/dotnet/DDDCourse/src/Core/Core/ObjectMapper/IObjectMapper.cs new file mode 100644 index 0000000..08c28ac --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/ObjectMapper/IObjectMapper.cs @@ -0,0 +1,9 @@ +namespace Core.ObjectMapper +{ + public interface IObjectMapper + { + TDestination MapTo(TSource source, TDestination destination); + + TDestination MapTo(object source); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/RealtimeNotifier/IRealtimeNotifier.cs b/dotnet/DDDCourse/src/Core/Core/RealtimeNotifier/IRealtimeNotifier.cs new file mode 100644 index 0000000..4fbbbbf --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/RealtimeNotifier/IRealtimeNotifier.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Core.RealtimeNotifier +{ + public interface IRealtimeNotifier + { + Task Notify(string topic, string body); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Repositories/IRepository{T}.cs b/dotnet/DDDCourse/src/Core/Core/Repositories/IRepository{T}.cs new file mode 100644 index 0000000..2edf900 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Repositories/IRepository{T}.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +using Core.Aggregates; + +namespace Core.Repositories +{ + public interface IRepository where T : AggregateRoot + { + Task Get(Func expression); + + Task> GetAll(); + + Task> GetAll(Func expression); + + Task Save(T aggregate); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Session/ISession.cs b/dotnet/DDDCourse/src/Core/Core/Session/ISession.cs new file mode 100644 index 0000000..812dbca --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Session/ISession.cs @@ -0,0 +1,11 @@ +namespace Core.Session +{ + public interface ISession + { + string Username { get; } + + string Email { get; } + + string UserId { get; } + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Uow/IUnitOfWork.cs b/dotnet/DDDCourse/src/Core/Core/Uow/IUnitOfWork.cs new file mode 100644 index 0000000..761997b --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Uow/IUnitOfWork.cs @@ -0,0 +1,10 @@ +using System; +using System.Threading.Tasks; + +namespace Core.Uow +{ + public interface IUnitOfWork : IDisposable + { + Task Complete(); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/Uow/IUnitOfWorkManager.cs b/dotnet/DDDCourse/src/Core/Core/Uow/IUnitOfWorkManager.cs new file mode 100644 index 0000000..c732371 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/Uow/IUnitOfWorkManager.cs @@ -0,0 +1,9 @@ +using System.Transactions; + +namespace Core.Uow +{ + public interface IUnitOfWorkManager + { + IUnitOfWork Begin(IsolationLevel isolationLevel); + } +} diff --git a/dotnet/DDDCourse/src/Core/Core/ValueObjects/ValueObject.cs b/dotnet/DDDCourse/src/Core/Core/ValueObjects/ValueObject.cs new file mode 100644 index 0000000..c8218d0 --- /dev/null +++ b/dotnet/DDDCourse/src/Core/Core/ValueObjects/ValueObject.cs @@ -0,0 +1,95 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace Core.ValueObjects +{ + //Inspired from https://blogs.msdn.microsoft.com/cesardelatorre/2011/06/06/implementing-a-value-object-base-class-supertype-patternddd-patterns-related/ + /// + /// Base class for value objects. + /// + /// The type of the value object. + public abstract class ValueObject : IEquatable + where TValueObject : ValueObject + { + public bool Equals(TValueObject other) + { + if ((object)other == null) + { + return false; + } + + PropertyInfo[] publicProperties = GetType().GetProperties(); + if (!publicProperties.Any()) + { + return true; + } + + return publicProperties.All(property => Equals(property.GetValue(this, null), property.GetValue(other, null))); + } + + public override bool Equals(object obj) + { + if (obj == null) + { + return false; + } + + var item = obj as ValueObject; + return (object)item != null && Equals((TValueObject)item); + } + + public override int GetHashCode() + { + const int index = 1; + const int initialHasCode = 31; + + PropertyInfo[] publicProperties = GetType().GetProperties(); + + if (!publicProperties.Any()) + { + return initialHasCode; + } + + int hashCode = initialHasCode; + var changeMultiplier = false; + + foreach (PropertyInfo property in publicProperties) + { + object value = property.GetValue(this, null); + + if (value == null) + { + //support {"a",null,null,"a"} != {null,"a","a",null} + hashCode = hashCode ^ (index * 13); + continue; + } + + hashCode = hashCode * (changeMultiplier ? 59 : 114) + value.GetHashCode(); + changeMultiplier = !changeMultiplier; + } + + return hashCode; + } + + public static bool operator ==(ValueObject x, ValueObject y) + { + if (ReferenceEquals(x, y)) + { + return true; + } + + if ((object)x == null || (object)y == null) + { + return false; + } + + return x.Equals(y); + } + + public static bool operator !=(ValueObject x, ValueObject y) + { + return !(x == y); + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Domain.csproj b/dotnet/DDDCourse/src/Domain/Domain.csproj new file mode 100644 index 0000000..9885599 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Domain.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + + + + + + + + diff --git a/dotnet/DDDCourse/src/Domain/Products/DomainEventHandlers/ProductCreatedEventHandler.cs b/dotnet/DDDCourse/src/Domain/Products/DomainEventHandlers/ProductCreatedEventHandler.cs new file mode 100644 index 0000000..f4ef472 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/DomainEventHandlers/ProductCreatedEventHandler.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; + +using Core.Bus; + +using Products.Events; + +namespace Products.DomainEventHandlers +{ + public class ProductCreatedEventHandler : IHandles + { + public Task Handle(ProductCreatedEvent message) + { + //Do some domain event actions... + //Pass message to other BoundedContexts or AggregateRoots + + return Task.CompletedTask; + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Entities/ProductImage.cs b/dotnet/DDDCourse/src/Domain/Products/Entities/ProductImage.cs new file mode 100644 index 0000000..f0eefaf --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Entities/ProductImage.cs @@ -0,0 +1,42 @@ +using System; + +using Core.Entities; + +using Products.Events; + +namespace Products.Entities +{ + public class ProductImage : Entity + { + public ProductImage() + { + Register(@event => + { + Product = @event.Product; + ImageUrl = @event.Url; + ShowOrder = @event.Order; + }); + } + + public virtual Product Product { get; private set; } + + public virtual string ImageUrl { get; private set; } + + public virtual int ShowOrder { get; private set; } + + public static ImageAddedEvent ImageAddedToProduct(Product product, string url, int order) + { + if (string.IsNullOrEmpty(url)) + { + throw new ArgumentNullException("url"); + } + + if (order <= 0) + { + throw new ArgumentException("order cannot be 0 or less"); + } + + return new ImageAddedEvent(product, url, order); + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Events/ImageAddedEvent.cs b/dotnet/DDDCourse/src/Domain/Products/Events/ImageAddedEvent.cs new file mode 100644 index 0000000..6f2f1a9 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Events/ImageAddedEvent.cs @@ -0,0 +1,18 @@ +using Core.Bus; + +namespace Products.Events +{ + public class ImageAddedEvent : Event + { + public int Order; + public Product Product; + public string Url; + + public ImageAddedEvent(Product product, string url, int order) + { + Order = order; + Url = url; + Product = product; + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Events/ProductCreatedEvent.cs b/dotnet/DDDCourse/src/Domain/Products/Events/ProductCreatedEvent.cs new file mode 100644 index 0000000..6b50026 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Events/ProductCreatedEvent.cs @@ -0,0 +1,19 @@ +using Core; +using Core.Bus; + +namespace Products.Events +{ + public class ProductCreatedEvent : Event + { + public string Barcode; + public string Code; + public string Name; + + public ProductCreatedEvent(string barcode, string code, string name) + { + Barcode = barcode; + Code = code; + Name = name; + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Exceptions/AggregateDuplicatedException.cs b/dotnet/DDDCourse/src/Domain/Products/Exceptions/AggregateDuplicatedException.cs new file mode 100644 index 0000000..a9ca40e --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Exceptions/AggregateDuplicatedException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Products.Exceptions +{ + public class AggregateDuplicatedException : Exception + { + public AggregateDuplicatedException(string message) : base(message) + { + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Exceptions/BarcodeExceedsMaximumLengthException.cs b/dotnet/DDDCourse/src/Domain/Products/Exceptions/BarcodeExceedsMaximumLengthException.cs new file mode 100644 index 0000000..76dd8c0 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Exceptions/BarcodeExceedsMaximumLengthException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Products.Exceptions +{ + public class BarcodeExceedsMaximumLengthException : Exception + { + public BarcodeExceedsMaximumLengthException(string message) : base(message) + { + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Exceptions/BusinessException.cs b/dotnet/DDDCourse/src/Domain/Products/Exceptions/BusinessException.cs new file mode 100644 index 0000000..63bf0fa --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Exceptions/BusinessException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Products.Exceptions +{ + public class BusinessException : Exception + { + public BusinessException(string message) : base(message) + { + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Product.cs b/dotnet/DDDCourse/src/Domain/Products/Product.cs new file mode 100644 index 0000000..504a601 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Product.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using System.Linq; + +using Core.Aggregates; + +using Products.Entities; +using Products.Events; +using Products.Exceptions; +using Products.ValueObjects; + +namespace Products +{ + public class Product : AggregateRoot + { + private const int MaxBarcodeLength = 40; + + private Product() + { + ProductImages = new List(); + } + + public virtual string Name { get; private set; } + + public virtual string Barcode { get; private set; } + + public virtual string Code { get; private set; } + + public virtual ICollection ProductImages { get; private set; } + + public virtual Price Price { get; private set; } + + public static Product Create(string name, string code, string barcode) + { + if (barcode.Length > MaxBarcodeLength) + { + throw new BarcodeExceedsMaximumLengthException($"Product creation for {barcode} exceeds maximum length of {MaxBarcodeLength}"); + } + + var product = new Product(); + product.RaiseEvent(new ProductCreatedEvent(barcode, code, name)); + return product; + } + + internal void Apply(ProductCreatedEvent @event) + { + Name = @event.Name; + Barcode = @event.Barcode; + Code = @event.Code; + } + + public void AddImage(string url, int order) + { + if (ProductImages.Any(x => x.ShowOrder == order)) { throw new BusinessException($"Image order already defined for Product:{Id}"); } + + RaiseEvent( + ProductImage.ImageAddedToProduct(this, url, order) + ); + } + + internal void Apply(ImageAddedEvent @event) + { + var image = new ProductImage(); + image.Route(@event); + ProductImages.Add(image); + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Repositories/ProductRepository.cs b/dotnet/DDDCourse/src/Domain/Products/Repositories/ProductRepository.cs new file mode 100644 index 0000000..0847b50 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Repositories/ProductRepository.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; + +using Core; +using Core.Bus; +using Core.Repositories; + +namespace Products.Repositories +{ + public class ProductRepository : IRepository + { + private readonly IEventPublisher _bus; + private readonly ConcurrentBag _db = new ConcurrentBag(); + + public ProductRepository(IEventPublisher bus) + { + _bus = bus; + } + + public Task Get(Func expression) + { + Product product = _db.FirstOrDefault(expression); + + return Task.FromResult(product); + } + + public Task> GetAll() + { + return Task.FromResult(_db.ToList()); + } + + public Task> GetAll(Func expression) + { + return Task.FromResult(_db.Where(expression).ToList()); + } + + public Task Save(Product aggregate) + { + ImmutableList events = aggregate.GetUncommittedEvents(); + + _db.Add(aggregate); + + events.ForEach(@event => _bus.Publish(@event)); + + aggregate.MarkEventsAsHandled(); + + return Task.FromResult(0); + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Services/IProductDomainService.cs b/dotnet/DDDCourse/src/Domain/Products/Services/IProductDomainService.cs new file mode 100644 index 0000000..881e99f --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Services/IProductDomainService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Products.Services +{ + public interface IProductDomainService + { + Task Create(string name, string code, string barcode); + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/Services/ProductDomainService.cs b/dotnet/DDDCourse/src/Domain/Products/Services/ProductDomainService.cs new file mode 100644 index 0000000..add186d --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/Services/ProductDomainService.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; + +using Core.Repositories; + +using Products.Exceptions; + +namespace Products.Services +{ + public class ProductDomainService : IProductDomainService + { + private readonly IRepository _repository; + + public ProductDomainService(IRepository repository) + { + _repository = repository; + } + + public async Task Create(string name, string code, string barcode) + { + Product existing = await _repository.Get(x => x.Barcode == barcode); + + if (existing != null) throw new AggregateDuplicatedException($"Duplicate Product creation attempt for {barcode}"); + + Product product = Product.Create(name, code, barcode); + + await _repository.Save(product); + } + } +} diff --git a/dotnet/DDDCourse/src/Domain/Products/ValueObjects/Price.cs b/dotnet/DDDCourse/src/Domain/Products/ValueObjects/Price.cs new file mode 100644 index 0000000..6e3fd37 --- /dev/null +++ b/dotnet/DDDCourse/src/Domain/Products/ValueObjects/Price.cs @@ -0,0 +1,16 @@ +using Core.ValueObjects; + +namespace Products.ValueObjects +{ + public class Price : ValueObject + { + public decimal Amount; + public string Currency; + + public Price(decimal amount, string currency) + { + Amount = amount; + Currency = currency; + } + } +} diff --git a/dotnet/DDDCourse/src/WebApi/Products/ProductController.cs b/dotnet/DDDCourse/src/WebApi/Products/ProductController.cs new file mode 100644 index 0000000..c717385 --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/Products/ProductController.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; + +using Core.Bus; + +using Microsoft.AspNetCore.Mvc; + +using Products.Commands; + +namespace Products +{ + [Route("products")] + public class ProductController : ControllerBase + { + private readonly ICommandSender _bus; + + public ProductController(IBus bus) + { + _bus = bus; + } + + [Route("create")] + [HttpPost] + public Task Create(CreateProductCommand command) + { + return _bus.Send(command); + } + } +} diff --git a/dotnet/DDDCourse/src/WebApi/Products/ProductReadController.cs b/dotnet/DDDCourse/src/WebApi/Products/ProductReadController.cs new file mode 100644 index 0000000..55b65be --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/Products/ProductReadController.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Mvc; + +using Products.Dtos; +using Products.ReadModel; + +namespace Products +{ + [Route("products/read/")] + public class ProductReadController : Controller + { + private readonly IProductReadModel _readModel; + + public ProductReadController(IProductReadModel readModel) + { + _readModel = readModel; + } + + [HttpGet] + [Route("by/barcode/{barcode}")] + public Task GetByBarcode(string barcode) + { + return _readModel.GetByBarcode(barcode); + } + } +} diff --git a/dotnet/DDDCourse/src/WebApi/Program.cs b/dotnet/DDDCourse/src/WebApi/Program.cs new file mode 100644 index 0000000..83fd550 --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/Program.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; + +public class Program +{ + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) + { + return WebHost.CreateDefaultBuilder(args) + .UseStartup() + .Build(); + } +} diff --git a/dotnet/DDDCourse/src/WebApi/Properties/launchSettings.json b/dotnet/DDDCourse/src/WebApi/Properties/launchSettings.json new file mode 100644 index 0000000..87e9414 --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:8608/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "/", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Product": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "/", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:8609/" + } + } +} diff --git a/dotnet/DDDCourse/src/WebApi/Startup.cs b/dotnet/DDDCourse/src/WebApi/Startup.cs new file mode 100644 index 0000000..5f0ef78 --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/Startup.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +public class Startup +{ + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + + //var objectMapper = new MapsterObjectMapper(); + + //var bus = new InMemoryBus(); + //var handler = new ProductAppService(new ProductDomainService(new ProductRepository(bus))); + //bus.Register(command => handler.Handle(command)); + //var repository = new ProductRepository(bus); + + //services.AddTransient(provider => new ProductReadModel(repository, objectMapper)); + //services.AddSingleton(provider => bus); + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseMvc(); + } +} diff --git a/dotnet/DDDCourse/src/WebApi/WebApi.csproj b/dotnet/DDDCourse/src/WebApi/WebApi.csproj new file mode 100644 index 0000000..6c06826 --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/WebApi.csproj @@ -0,0 +1,24 @@ + + + + netcoreapp2.0 + + + + + + + + + + + + + + + + + + + + diff --git a/dotnet/DDDCourse/src/WebApi/appsettings.Development.json b/dotnet/DDDCourse/src/WebApi/appsettings.Development.json new file mode 100644 index 0000000..fa8ce71 --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/dotnet/DDDCourse/src/WebApi/appsettings.json b/dotnet/DDDCourse/src/WebApi/appsettings.json new file mode 100644 index 0000000..26bb0ac --- /dev/null +++ b/dotnet/DDDCourse/src/WebApi/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Warning" + } + }, + "Console": { + "LogLevel": { + "Default": "Warning" + } + } + } +} diff --git a/DependencyInjectionCourse/Dependency Injection.pptx b/dotnet/DependencyInjectionCourse/Dependency Injection.pptx similarity index 99% rename from DependencyInjectionCourse/Dependency Injection.pptx rename to dotnet/DependencyInjectionCourse/Dependency Injection.pptx index 68f1e89..ef255f5 100644 Binary files a/DependencyInjectionCourse/Dependency Injection.pptx and b/dotnet/DependencyInjectionCourse/Dependency Injection.pptx differ diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/AutofacChillContainer.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/AutofacChillContainer.cs new file mode 100644 index 0000000..1845610 --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/AutofacChillContainer.cs @@ -0,0 +1,107 @@ +using Autofac; +using Autofac.Builder; +using Autofac.Core; +using Chill; +using System; + +namespace Chill.Autofac +{ + internal class AutofacChillContainer : IChillContainer + { + private ILifetimeScope _container; + private ContainerBuilder _containerBuilder; + + public AutofacChillContainer() + : this(new ContainerBuilder()) + { + } + + public AutofacChillContainer(ILifetimeScope container) + { + _container = container; + } + + public AutofacChillContainer(ContainerBuilder containerBuilder) + { + _containerBuilder = containerBuilder; + } + + protected ILifetimeScope Container + { + get + { + if (_container == null) + _container = _containerBuilder.Build(); + return _container; + } + } + + public void Dispose() + { + Container.Dispose(); + } + + + public void RegisterType() where T : class + { + Container.ComponentRegistry.Register(RegistrationBuilder.ForType().InstancePerLifetimeScope().CreateRegistration()); + } + + public T Get(string key = null) where T : class + { + if (key == null) + { + return Container.Resolve(); + } + else + { + return Container.ResolveKeyed(key); + } + } + + public T Set(T valueToSet, string key = null) where T : class + { + if (key == null) + { + Container.ComponentRegistry + .Register(RegistrationBuilder.ForDelegate((c, p) => valueToSet) + .InstancePerLifetimeScope().CreateRegistration()); + + } + else + { + Container.ComponentRegistry + .Register(RegistrationBuilder.ForDelegate((c, p) => valueToSet) + .As(new KeyedService(key, typeof(T))) + .InstancePerLifetimeScope().CreateRegistration()); + } + return Get(); + } + + + public bool IsRegistered() where T : class + { + return IsRegistered(typeof(T)); + } + + public bool IsRegistered(System.Type type) + { + return Container.IsRegistered(type); + } + } + + public static class TestBaseExtensions + { + /// + /// Explicitly register a type so that it will be created from the chill container from now on. + /// + /// This is handy if you wish to create a concrete type from a container that typically doesn't allow + /// you to do so. (such as autofac) + /// + /// + public static void RegisterConcreteType(this TestBase testBase) where T : class + { + testBase.Container.RegisterType(); + } + } +} \ No newline at end of file diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/AutofacFakeItEasyMockingContainer.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/AutofacFakeItEasyMockingContainer.cs new file mode 100644 index 0000000..585915c --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/AutofacFakeItEasyMockingContainer.cs @@ -0,0 +1,25 @@ +using Autofac; +using Chill.Autofac; + +namespace Chill.AutofacFakeItEasy +{ + /// + /// An implementation of that uses Autofac and FakeItEasy to build objects + /// with mocked dependencies. + /// + internal class AutofacFakeItEasyMockingContainer : AutofacChillContainer + { + public AutofacFakeItEasyMockingContainer() + : base(CreateContainerBuilder()) + { + + } + + private static ContainerBuilder CreateContainerBuilder() + { + var builder = new ContainerBuilder(); + builder.RegisterSource(new FakeRegistrationHandler(false, false, false, null)); + return builder; + } + } +} \ No newline at end of file diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/DefaultChillContainer.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/DefaultChillContainer.cs new file mode 100644 index 0000000..248f3a1 --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/DefaultChillContainer.cs @@ -0,0 +1,5 @@ +using Chill; +using Chill.AutofacFakeItEasy; + +// This attribute defines which container will be used by default for this assembly +[assembly: ChillContainer(typeof(AutofacFakeItEasyMockingContainer))] \ No newline at end of file diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/FakeRegistrationHandler.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/FakeRegistrationHandler.cs new file mode 100644 index 0000000..9cee071 --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Chill/FakeRegistrationHandler.cs @@ -0,0 +1,155 @@ +// This software is part of the Autofac IoC container +// Copyright (c) 2007 - 2008 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Security; +using Autofac; +using Autofac.Builder; +using Autofac.Core; +using FakeItEasy; +using FakeItEasy.Creation; + +namespace Chill.AutofacFakeItEasy +{ + /// Resolves unknown interfaces and Fakes. + internal class FakeRegistrationHandler : IRegistrationSource + { + private readonly MethodInfo _createMethod; + private readonly bool _strict; + private readonly bool _callsBaseMethods; + private readonly bool _callsDoNothing; + private readonly Action _onFakeCreated; + + /// + /// Initializes a new instance of the class. + /// + /// Whether fakes should be created with strict semantics. + /// Whether fakes should call base methods. + /// Whether calls to fakes should do nothing. + /// An action to perform on a fake when it is created. + [SecurityCritical] + public FakeRegistrationHandler(bool strict, bool callsBaseMethods, bool callsDoNothing, Action onFakeCreated) + { + this._strict = strict; + this._callsBaseMethods = callsBaseMethods; + this._callsDoNothing = callsDoNothing; + this._onFakeCreated = onFakeCreated; + + // NOTE (adamralph): inspired by http://blog.functionalfun.net/2009/10/getting-methodinfo-of-generic-method.html + Expression create = () => this.CreateFake(); + this._createMethod = (create.Body as MethodCallExpression).Method.GetGenericMethodDefinition(); + } + + /// + /// Gets whether the registrations provided by this source are 1:1 adapters on top + /// of other components (I.e. like Meta, Func or Owned.) + /// + public bool IsAdapterForIndividualComponents + { + get { return false; } + } + + /// + /// Retrieve registrations for an unregistered service, to be used + /// by the container. + /// + /// The service that was requested. + /// A function that will return existing registrations for a service. + /// Registrations providing the service. + [SecuritySafeCritical] + public IEnumerable RegistrationsFor( + Service service, Func> registrationAccessor) + { + if (service == null) + { + throw new ArgumentNullException("service"); + } + + var typedService = service as IServiceWithType; + if (typedService == null || + !typedService.ServiceType.IsInterface || + typedService.ServiceType.IsGenericType && + typedService.ServiceType.GetGenericTypeDefinition() == typeof(IEnumerable<>) || + typedService.ServiceType.IsArray || + typeof(IStartable).IsAssignableFrom(typedService.ServiceType)) + { + return Enumerable.Empty(); + } + + var rb = RegistrationBuilder.ForDelegate((c, p) => this.CreateFake(typedService)) + .As(service) + .InstancePerLifetimeScope(); + + return new[] { rb.CreateRegistration() }; + } + + /// + /// Creates a fake object. + /// + /// The typed service. + /// A fake object. + [SecuritySafeCritical] + private object CreateFake(IServiceWithType typedService) + { + return this._createMethod.MakeGenericMethod(new[] { typedService.ServiceType }).Invoke(this, null); + } + + [SecuritySafeCritical] + private T CreateFake() + { + var fake = A.Fake(this.ApplyOptions); + + if (this._callsBaseMethods) + { + A.CallTo(fake).CallsBaseMethod(); + } + + if (this._callsDoNothing) + { + A.CallTo(fake).DoesNothing(); + } + + return fake; + } + + [SecuritySafeCritical] + private void ApplyOptions(IFakeOptions options)//IFakeOptionsBuilder [to] IFakeOptions + { + if (this._strict) + { + options.Strict(); + } + + if (this._onFakeCreated != null) + { + options.ConfigureFake(x => this._onFakeCreated(x));//OnFakeCreated(x=>) [to] ConfigureFake(x=>) + } + } + } +} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoSubstituteAttribute.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoSubstituteAttribute.cs similarity index 66% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoSubstituteAttribute.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoSubstituteAttribute.cs index 8945091..0ced0d9 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoSubstituteAttribute.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Conventions/AutoSubstituteAttribute.cs @@ -1,5 +1,5 @@ using Ploeh.AutoFixture; -using Ploeh.AutoFixture.AutoNSubstitute; +using Ploeh.AutoFixture.AutoFakeItEasy; using Ploeh.AutoFixture.Xunit2; namespace DependencyInjectionCourse.Tests.Conventions @@ -7,7 +7,7 @@ namespace DependencyInjectionCourse.Tests.Conventions public class AutoDataSubstituteAttribute : AutoDataAttribute { public AutoDataSubstituteAttribute() - : base(new Fixture().Customize(new AutoConfiguredNSubstituteCustomization())) + : base(new Fixture().Customize(new AutoFakeItEasyCustomization())) { } } diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.csproj b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.csproj new file mode 100644 index 0000000..779ba4c --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.csproj @@ -0,0 +1,207 @@ + + + + + + Debug + AnyCPU + {11C33D6E-DC39-41EB-A6FF-E4CA754EB15A} + Library + Properties + DependencyInjectionCourse.Tests + DependencyInjectionCourse.Tests + v4.6.2 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Autofac.4.1.1\lib\net45\Autofac.dll + True + + + ..\packages\Autofac.Extras.FakeItEasy.4.0.0\lib\net451\Autofac.Extras.FakeItEasy.dll + + + ..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll + + + ..\packages\Chill.2.6.0\lib\net45\Chill.dll + + + ..\packages\FakeItEasy.2.0.0\lib\net40\FakeItEasy.dll + + + ..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll + + + ..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll + + + ..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll + + + ..\packages\AutoFixture.3.50.2\lib\net40\Ploeh.AutoFixture.dll + True + + + ..\packages\AutoFixture.AutoFakeItEasy.3.50.2\lib\net40\Ploeh.AutoFixture.AutoFakeItEasy.dll + + + ..\packages\AutoFixture.Xunit2.3.50.2\lib\net45\Ploeh.AutoFixture.Xunit2.dll + True + + + + ..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll + + + + ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll + + + + ..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll + + + ..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll + + + ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + + + + ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll + + + ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + + + ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll + + + ..\packages\System.Net.Http.4.3.1\lib\net46\System.Net.Http.dll + + + ..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll + + + + ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll + + + ..\packages\System.Reflection.TypeExtensions.4.3.0\lib\net462\System.Reflection.TypeExtensions.dll + + + ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + + + ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll + + + ..\packages\System.Runtime.InteropServices.4.3.0\lib\net462\System.Runtime.InteropServices.dll + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + + + + + + + + ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + + + ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll + True + + + ..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll + True + + + ..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll + True + + + ..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll + True + + + + + + + + + + + + + + + + + + + + + + + + {9DB19A34-0D4C-4F7A-9F4D-2E54C15E1634} + DependencyInjectionCourse + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.v3.ncrunchproject b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.v3.ncrunchproject similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.v3.ncrunchproject rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/DependencyInjectionCourse.Tests.v3.ncrunchproject diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_1.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_1.cs similarity index 80% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_1.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_1.cs index a08558e..8b4334d 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_1.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_1.cs @@ -2,9 +2,9 @@ using DependencyInjectionCourse.ExternalDependencies; using DependencyInjectionCourse.Order; -using FluentAssertions; +using FakeItEasy; -using NSubstitute; +using FluentAssertions; using Xunit; @@ -16,23 +16,22 @@ namespace DependencyInjectionCourse.Tests public class OrderService_Tests_1 { [Fact] - public void without_dependency_injection() + public void order_should_be_done_successfully() { //----------------------------------------------------------------------------------------------------------- // Arrange //----------------------------------------------------------------------------------------------------------- - var fakeCacheManager = Substitute.For(); - var fakeDependency1 = Substitute.For(); - var fakeDependency2 = Substitute.For(); - fakeCacheManager.Get("1").Returns(new Basket(1, 50)); - - // Dependency1'in içindeki Logger'a test yazarken ihtiyaç duyulduğu anda tekrar bi New'leme yapılması gerek! - // Dependency sayıları arttıkça New sayısı veya object passing artar, okunurluk azalır. - var sut = new OrderService(fakeCacheManager, fakeDependency1, fakeDependency2); + var fakeCacheManager = A.Fake(); + var fakeDependency1 = A.Fake(); + var fakeDependency2 = A.Fake(); + A.CallTo(() => fakeCacheManager.Get("1")).Returns(new Basket(1, 50)); //----------------------------------------------------------------------------------------------------------- // Act //----------------------------------------------------------------------------------------------------------- + // Dependency1'in içindeki Logger'a test yazarken ihtiyaç duyulduğu anda tekrar bi New'leme yapılması gerek! + // Dependency sayıları arttıkça New sayısı veya object passing artar, okunurluk azalır. + var sut = new OrderService(fakeCacheManager, fakeDependency1, fakeDependency2); OrderResult result = sut.DoOrder(1); //----------------------------------------------------------------------------------------------------------- @@ -40,6 +39,7 @@ public void without_dependency_injection() //----------------------------------------------------------------------------------------------------------- result.BasketId.Should().Be(1); result.Total.Should().Be(50); + A.CallTo(() => fakeDependency1.Salute()).MustHaveHappened(); } } } diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_2_With_DependencyInjection.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_2_With_DependencyInjection.cs similarity index 77% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_2_With_DependencyInjection.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_2_With_DependencyInjection.cs index 5114c02..f53b0e8 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_2_With_DependencyInjection.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_2_With_DependencyInjection.cs @@ -4,9 +4,9 @@ using DependencyInjectionCourse.ExternalDependencies; using DependencyInjectionCourse.Order; -using FluentAssertions; +using FakeItEasy; -using NSubstitute; +using FluentAssertions; using Xunit; @@ -20,17 +20,17 @@ namespace DependencyInjectionCourse.Tests public class OrderService_Tests_2_With_DependencyInjection : TestBaseWithLocalIoc { [Fact] - public void with_pure_dependency_injection() + public void order_should_be_done_successfully() { //----------------------------------------------------------------------------------------------------------- // Arrange //----------------------------------------------------------------------------------------------------------- Building(builder => { - var fakeDepdency1 = Substitute.For(); - var fakeDepdency2 = Substitute.For(); - var fakeCacheManager = Substitute.For(); - fakeCacheManager.Get("1").Returns(new Basket(1, 50)); + var fakeDepdency1 = A.Fake(); + var fakeDepdency2 = A.Fake(); + var fakeCacheManager = A.Fake(); + A.CallTo(() => fakeCacheManager.Get("1")).Returns(new Basket(1, 50)); builder.Register(context => fakeDepdency1); builder.Register(context => fakeDepdency2); @@ -38,11 +38,13 @@ public void with_pure_dependency_injection() builder.RegisterType().As(); }); - var sut = Use(); - //----------------------------------------------------------------------------------------------------------- // Act //----------------------------------------------------------------------------------------------------------- + + // We get rid of the object creation which means object newing! + var sut = The(); + OrderResult result = sut.DoOrder(1); //----------------------------------------------------------------------------------------------------------- @@ -50,6 +52,7 @@ public void with_pure_dependency_injection() //----------------------------------------------------------------------------------------------------------- result.BasketId.Should().Be(1); result.Total.Should().Be(50); + A.CallTo(() => The().Salute()).MustHaveHappened(); } } } diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_3_With_DependencyInjection_And_AutoFixture.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_3_With_DependencyInjection_And_AutoFixture.cs similarity index 88% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_3_With_DependencyInjection_And_AutoFixture.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_3_With_DependencyInjection_And_AutoFixture.cs index 87c5bf3..f887a32 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_3_With_DependencyInjection_And_AutoFixture.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_3_With_DependencyInjection_And_AutoFixture.cs @@ -5,9 +5,9 @@ using DependencyInjectionCourse.Order; using DependencyInjectionCourse.Tests.Conventions; -using FluentAssertions; +using FakeItEasy; -using NSubstitute; +using FluentAssertions; using Xunit; @@ -21,7 +21,7 @@ public class OrderService_Tests_3_With_DependencyInjection_And_AutoFixture : Tes { [Theory] [AutoDataSubstitute] - public void with_pure_dependency_injection_autofixture( + public void order_should_be_done_successfully( IDependency1 fakeDependency1, IDependency2 fakeDependency2, ICacheManager fakeCacheManager @@ -32,7 +32,7 @@ ICacheManager fakeCacheManager //----------------------------------------------------------------------------------------------------------- Building(builder => { - fakeCacheManager.Get("1").Returns(new Basket(1, 50)); + A.CallTo(() => fakeCacheManager.Get("1")).Returns(new Basket(1, 50)); builder.Register(context => fakeDependency1); builder.Register(context => fakeDependency2); @@ -40,11 +40,11 @@ ICacheManager fakeCacheManager builder.RegisterType().As(); }); - var sut = Use(); - //----------------------------------------------------------------------------------------------------------- // Act //----------------------------------------------------------------------------------------------------------- + var sut = The(); + OrderResult result = sut.DoOrder(1); //----------------------------------------------------------------------------------------------------------- @@ -52,6 +52,7 @@ ICacheManager fakeCacheManager //----------------------------------------------------------------------------------------------------------- result.BasketId.Should().Be(1); result.Total.Should().Be(50); + A.CallTo(() => fakeDependency1.Salute()).MustHaveHappened(); } } } diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_5_With_DependencyInection_And_AutoSubstitutingContainer_SecondApproach.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer.cs similarity index 71% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_5_With_DependencyInection_And_AutoSubstitutingContainer_SecondApproach.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer.cs index 3b2be9c..7da6faa 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_5_With_DependencyInection_And_AutoSubstitutingContainer_SecondApproach.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer.cs @@ -2,32 +2,32 @@ using DependencyInjectionCourse.ExternalDependencies; using DependencyInjectionCourse.Order; -using FluentAssertions; +using FakeItEasy; -using NSubstitute; +using FluentAssertions; using Xunit; namespace DependencyInjectionCourse.Tests { /// - /// Uses https://github.com/MRCollective/AutofacContrib.NSubstitute + /// Auto-Mocking container aspect /// - /// - public class OrderService_Tests_5_With_DependencyInection_And_AutoSubstitutingContainer_SecondApproach : TestBaseWithAutoSubstituteIoc + /// + public class OrderService_Tests_4_With_DependencyInection_And_AutoSubstitutingContainer : TestBaseWithAutoFakingIoc { [Fact] - public void with_dependency_injection_and_automocking_container() + public void order_should_be_done_successfully() { //----------------------------------------------------------------------------------------------------------- // Arrange //----------------------------------------------------------------------------------------------------------- - AFake().Get("1").Returns(new Basket(1, 50)); - IOrderService sut = Use(); + A.CallTo(() => Fake().Get("1")).Returns(new Basket(1, 50)); //----------------------------------------------------------------------------------------------------------- // Act //----------------------------------------------------------------------------------------------------------- + IOrderService sut = The(); OrderResult result = sut.DoOrder(1); //----------------------------------------------------------------------------------------------------------- @@ -35,7 +35,7 @@ public void with_dependency_injection_and_automocking_container() //----------------------------------------------------------------------------------------------------------- result.BasketId.Should().Be(1); result.Total.Should().Be(50); - AFake().Received().Salute(); + A.CallTo(() => Fake().Salute()).MustHaveHappened(); } } } diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_6_With_Chill.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_5_With_Chill.cs similarity index 62% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_6_With_Chill.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_5_With_Chill.cs index 662db82..e230d1a 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_6_With_Chill.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/OrderService_Tests_5_With_Chill.cs @@ -4,9 +4,9 @@ using DependencyInjectionCourse.ExternalDependencies; using DependencyInjectionCourse.Order; -using FluentAssertions; +using FakeItEasy; -using NSubstitute; +using FluentAssertions; using Xunit; @@ -16,26 +16,25 @@ namespace DependencyInjectionCourse.Tests /// This is another Container based approach! /// Uses https://github.com/Erwinvandervalk/Chill /// - public class OrderService_Tests_6_With_Chill : GivenSubject + public class OrderService_Tests_5_With_Chill : GivenSubject { - public OrderService_Tests_6_With_Chill() + public OrderService_Tests_5_With_Chill() { Given(() => { SetThe().To(new Basket(1, 50)); - UseThe(Substitute.For()).Get("1").Returns(The()); - UseThe(Substitute.For()); - UseThe(Substitute.For()); + A.CallTo(() => The().Get("1")).Returns(The()); }); When(() => Subject.DoOrder(1)); } [Fact] - public void with_chill_behaviour_driven_design_as_scoped_with_single_operation_responsibility() + public void order_should_be_done_successfully() { Result.BasketId.Should().Be(1); Result.Total.Should().Be(50); + A.CallTo(() => The().Salute()).MustHaveHappened(); } } } diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Properties/AssemblyInfo.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Properties/AssemblyInfo.cs similarity index 97% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Properties/AssemblyInfo.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Properties/AssemblyInfo.cs index 961cdff..b0f3369 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Properties/AssemblyInfo.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/Properties/AssemblyInfo.cs @@ -1,10 +1,10 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. + [assembly: AssemblyTitle("DependencyInjectionCourse.Tests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] @@ -17,9 +17,11 @@ // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("11c33d6e-dc39-41eb-a6ff-e4ca754eb15a")] // Version information for an assembly consists of the following four values: @@ -32,5 +34,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] + [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoFakingIoc.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoFakingIoc.cs new file mode 100644 index 0000000..5e5ae7b --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithAutoFakingIoc.cs @@ -0,0 +1,31 @@ +using System; + +using Autofac.Extras.FakeItEasy; + +namespace DependencyInjectionCourse.Tests +{ + public abstract class TestBaseWithAutoFakingIoc : IDisposable + { + protected AutoFake FakeResolver; + + protected TestBaseWithAutoFakingIoc() + { + FakeResolver = new AutoFake(); + } + + public void Dispose() + { + FakeResolver?.Dispose(); + } + + protected T Fake() + { + return FakeResolver.Resolve(); + } + + protected TService The() + { + return FakeResolver.Provide(); + } + } +} diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithLocalIoc.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithLocalIoc.cs similarity index 95% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithLocalIoc.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithLocalIoc.cs index 739d6c3..8ae7ddc 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithLocalIoc.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/TestBaseWithLocalIoc.cs @@ -20,7 +20,7 @@ protected void Building(Action builderAction) Resolver = Builder.Build(); } - protected T Use() + protected T The() { return Resolver.Resolve(); } diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/app.config b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/app.config new file mode 100644 index 0000000..0da736e --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/app.config @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/packages.config b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/packages.config new file mode 100644 index 0000000..3561b5e --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.Tests/packages.config @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.sln b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.sln similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.sln rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.sln diff --git a/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchsolution b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchsolution new file mode 100644 index 0000000..10420ac --- /dev/null +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchsolution @@ -0,0 +1,6 @@ + + + True + True + + \ No newline at end of file diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/App.config b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/App.config similarity index 79% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/App.config rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/App.config index 319cc62..8b4e4f4 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/App.config +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/App.config @@ -1,8 +1,10 @@ - + - - - + + + diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Basket.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Basket.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Basket.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Basket.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheManager.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheManager.cs similarity index 95% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheManager.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheManager.cs index 8803e64..0cb2089 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheManager.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheManager.cs @@ -1,7 +1,5 @@ using System.Collections.Concurrent; -using JetBrains.Annotations; - namespace DependencyInjectionCourse.Cache { public class CacheManager : ICacheManager diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheStarter.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheStarter.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheStarter.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/CacheStarter.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/ICacheManager.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/ICacheManager.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/ICacheManager.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/ICacheManager.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/NullCacheManager.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/NullCacheManager.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/NullCacheManager.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Cache/NullCacheManager.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Check.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Check.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Check.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Check.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.csproj b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.csproj similarity index 96% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.csproj rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.csproj index 01bca61..2e3d855 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.csproj +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.csproj @@ -33,9 +33,9 @@ 4 - - ..\packages\Autofac.4.3.0\lib\net45\Autofac.dll - True + + False + ..\packages\Autofac.4.1.1\lib\net45\Autofac.dll ..\packages\Autofac.Extras.DynamicProxy.4.2.1\lib\net45\Autofac.Extras.DynamicProxy.dll diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchproject b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchproject similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchproject rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse.v3.ncrunchproject diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency1.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency1.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency1.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency1.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency2.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency2.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency2.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency2.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency3.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency3.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency3.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/ExternalDependencies/Dependency3.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/AuditInterceptor.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/AuditInterceptor.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/AuditInterceptor.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/AuditInterceptor.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/SecurityInterceptor.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/SecurityInterceptor.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/SecurityInterceptor.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Interceptors/SecurityInterceptor.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ConsoleLogger.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ConsoleLogger.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ConsoleLogger.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ConsoleLogger.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ILogger.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ILogger.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ILogger.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/ILogger.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/NullLogger.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/NullLogger.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/NullLogger.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Logger/NullLogger.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/IOrderService.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/IOrderService.cs similarity index 67% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/IOrderService.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/IOrderService.cs index 359bac2..409ad5c 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/IOrderService.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/IOrderService.cs @@ -4,6 +4,7 @@ namespace DependencyInjectionCourse.Order { public interface IOrderService { - [NotNull] OrderResult DoOrder(int basketId); + [NotNull] + OrderResult DoOrder(int basketId); } } diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderResult.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderResult.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderResult.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderResult.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderService.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderService.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderService.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/OrderService.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/ResultBase.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/ResultBase.cs similarity index 100% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/ResultBase.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Order/ResultBase.cs diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Program.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Program.cs similarity index 99% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Program.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Program.cs index d9eebe3..322fbba 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Program.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Program.cs @@ -46,7 +46,6 @@ private static void Main(string[] args) IContainer container = builder.Build(); - var claims = Thread.CurrentPrincipal as ClaimsPrincipal; claims.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "User") })); diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Properties/AssemblyInfo.cs b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Properties/AssemblyInfo.cs similarity index 97% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Properties/AssemblyInfo.cs rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Properties/AssemblyInfo.cs index d9d524d..5340a00 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Properties/AssemblyInfo.cs +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/Properties/AssemblyInfo.cs @@ -1,10 +1,10 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. + [assembly: AssemblyTitle("DependencyInjectionCourse")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] @@ -17,9 +17,11 @@ // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("9db19a34-0d4c-4f7a-9f4d-2e54c15e1634")] // Version information for an assembly consists of the following four values: @@ -32,5 +34,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] + [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/packages.config b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/packages.config similarity index 89% rename from DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/packages.config rename to dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/packages.config index 24aec25..6189669 100644 --- a/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/packages.config +++ b/dotnet/DependencyInjectionCourse/DependencyInjectionCourse/DependencyInjectionCourse/packages.config @@ -1,4 +1,6 @@ - + diff --git a/Hangfire.Samples/.gitattributes b/dotnet/Hangfire.Samples/.gitattributes similarity index 100% rename from Hangfire.Samples/.gitattributes rename to dotnet/Hangfire.Samples/.gitattributes diff --git a/Hangfire.Samples/.gitignore b/dotnet/Hangfire.Samples/.gitignore similarity index 100% rename from Hangfire.Samples/.gitignore rename to dotnet/Hangfire.Samples/.gitignore diff --git a/Hangfire.Samples/.nuget/NuGet.Config b/dotnet/Hangfire.Samples/.nuget/NuGet.Config similarity index 100% rename from Hangfire.Samples/.nuget/NuGet.Config rename to dotnet/Hangfire.Samples/.nuget/NuGet.Config diff --git a/Hangfire.Samples/.nuget/NuGet.exe b/dotnet/Hangfire.Samples/.nuget/NuGet.exe similarity index 100% rename from Hangfire.Samples/.nuget/NuGet.exe rename to dotnet/Hangfire.Samples/.nuget/NuGet.exe diff --git a/Hangfire.Samples/.nuget/NuGet.targets b/dotnet/Hangfire.Samples/.nuget/NuGet.targets similarity index 100% rename from Hangfire.Samples/.nuget/NuGet.targets rename to dotnet/Hangfire.Samples/.nuget/NuGet.targets diff --git a/Hangfire.Samples/Hangfire.ConsoleApplication/App.config b/dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/App.config similarity index 100% rename from Hangfire.Samples/Hangfire.ConsoleApplication/App.config rename to dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/App.config diff --git a/Hangfire.Samples/Hangfire.ConsoleApplication/Hangfire.ConsoleApplication.csproj b/dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Hangfire.ConsoleApplication.csproj similarity index 100% rename from Hangfire.Samples/Hangfire.ConsoleApplication/Hangfire.ConsoleApplication.csproj rename to dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Hangfire.ConsoleApplication.csproj diff --git a/Hangfire.Samples/Hangfire.ConsoleApplication/Program.cs b/dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Program.cs similarity index 100% rename from Hangfire.Samples/Hangfire.ConsoleApplication/Program.cs rename to dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Program.cs diff --git a/Hangfire.Samples/Hangfire.ConsoleApplication/Properties/AssemblyInfo.cs b/dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Properties/AssemblyInfo.cs similarity index 100% rename from Hangfire.Samples/Hangfire.ConsoleApplication/Properties/AssemblyInfo.cs rename to dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Properties/AssemblyInfo.cs diff --git a/Hangfire.Samples/Hangfire.ConsoleApplication/Startup.cs b/dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Startup.cs similarity index 100% rename from Hangfire.Samples/Hangfire.ConsoleApplication/Startup.cs rename to dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/Startup.cs diff --git a/Hangfire.Samples/Hangfire.ConsoleApplication/packages.config b/dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/packages.config similarity index 100% rename from Hangfire.Samples/Hangfire.ConsoleApplication/packages.config rename to dotnet/Hangfire.Samples/Hangfire.ConsoleApplication/packages.config diff --git a/Hangfire.Samples/Hangfire.MvcApplication/App_Start/RouteConfig.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/App_Start/RouteConfig.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/App_Start/RouteConfig.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/App_Start/RouteConfig.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/Site.css b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/Site.css similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/Site.css rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/Site.css diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css.map b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css.map similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css.map rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.css.map diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css.map b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css.map similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css.map rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap-theme.min.css.map diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css.map b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css.map similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css.map rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.css.map diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css.map b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css.map similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css.map rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Content/bootstrap.min.css.map diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Controllers/HomeController.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Controllers/HomeController.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Controllers/HomeController.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Controllers/HomeController.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Global.asax b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Global.asax similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Global.asax rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Global.asax diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Global.asax.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Global.asax.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Global.asax.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Global.asax.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Hangfire.MvcApplication.csproj b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Hangfire.MvcApplication.csproj similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Hangfire.MvcApplication.csproj rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Hangfire.MvcApplication.csproj diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Properties/AssemblyInfo.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Properties/AssemblyInfo.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Properties/AssemblyInfo.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Properties/AssemblyInfo.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.js b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.js similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.js rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.js diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.min.js b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.min.js similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.min.js rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/bootstrap.min.js diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.intellisense.js b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.intellisense.js similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.intellisense.js rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.intellisense.js diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.js b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.js similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.js rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.js diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.js b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.js similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.js rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.js diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.map b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.map similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.map rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Scripts/jquery-2.2.3.min.map diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Startup.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Startup.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Startup.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Startup.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/TextBuffer.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/TextBuffer.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/TextBuffer.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/TextBuffer.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/TextBufferLogProvider.cs b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/TextBufferLogProvider.cs similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/TextBufferLogProvider.cs rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/TextBufferLogProvider.cs diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Views/Home/Index.cshtml b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/Home/Index.cshtml similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Views/Home/Index.cshtml rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/Home/Index.cshtml diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Views/Shared/_Layout.cshtml b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/Shared/_Layout.cshtml similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Views/Shared/_Layout.cshtml rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/Shared/_Layout.cshtml diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Views/_ViewStart.cshtml b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/_ViewStart.cshtml similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Views/_ViewStart.cshtml rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/_ViewStart.cshtml diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Views/web.config b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/web.config similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Views/web.config rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Views/web.config diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Web.Debug.config b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Web.Debug.config similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Web.Debug.config rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Web.Debug.config diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Web.Release.config b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Web.Release.config similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Web.Release.config rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Web.Release.config diff --git a/Hangfire.Samples/Hangfire.MvcApplication/Web.config b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/Web.config similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/Web.config rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/Web.config diff --git a/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.eot b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.eot rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.eot diff --git a/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.svg b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.svg rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.svg diff --git a/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.ttf b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.ttf rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.ttf diff --git a/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff diff --git a/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff2 b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff2 rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/fonts/glyphicons-halflings-regular.woff2 diff --git a/Hangfire.Samples/Hangfire.MvcApplication/packages.config b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/packages.config similarity index 93% rename from Hangfire.Samples/Hangfire.MvcApplication/packages.config rename to dotnet/Hangfire.Samples/Hangfire.MvcApplication/packages.config index 2631554..64c9423 100644 --- a/Hangfire.Samples/Hangfire.MvcApplication/packages.config +++ b/dotnet/Hangfire.Samples/Hangfire.MvcApplication/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Hangfire.Samples/Hangfire.Samples.sln b/dotnet/Hangfire.Samples/Hangfire.Samples.sln similarity index 100% rename from Hangfire.Samples/Hangfire.Samples.sln rename to dotnet/Hangfire.Samples/Hangfire.Samples.sln diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplication/App.config b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/App.config similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplication/App.config rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/App.config diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplication/Hangfire.WindowsServiceApplication.csproj b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Hangfire.WindowsServiceApplication.csproj similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplication/Hangfire.WindowsServiceApplication.csproj rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Hangfire.WindowsServiceApplication.csproj diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplication/Program.cs b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Program.cs similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplication/Program.cs rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Program.cs diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplication/Properties/AssemblyInfo.cs b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Properties/AssemblyInfo.cs similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplication/Properties/AssemblyInfo.cs rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Properties/AssemblyInfo.cs diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplication/Startup.cs b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Startup.cs similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplication/Startup.cs rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/Startup.cs diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplication/packages.config b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/packages.config similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplication/packages.config rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplication/packages.config diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/App.config b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/App.config similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/App.config rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/App.config diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Hangfire.WindowsServiceApplicationInstance2.csproj b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Hangfire.WindowsServiceApplicationInstance2.csproj similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Hangfire.WindowsServiceApplicationInstance2.csproj rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Hangfire.WindowsServiceApplicationInstance2.csproj diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Program.cs b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Program.cs similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Program.cs rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Program.cs diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Properties/AssemblyInfo.cs b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Properties/AssemblyInfo.cs similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Properties/AssemblyInfo.cs rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Properties/AssemblyInfo.cs diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Startup.cs b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Startup.cs similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Startup.cs rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/Startup.cs diff --git a/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/packages.config b/dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/packages.config similarity index 100% rename from Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/packages.config rename to dotnet/Hangfire.Samples/Hangfire.WindowsServiceApplicationInstance2/packages.config diff --git a/Hangfire.Samples/README.md b/dotnet/Hangfire.Samples/README.md similarity index 100% rename from Hangfire.Samples/README.md rename to dotnet/Hangfire.Samples/README.md diff --git a/QuartzSample/Abp.Quartz.JobExecuter/Abp.Quartz.ConsoleApp.csproj b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/Abp.Quartz.ConsoleApp.csproj similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/Abp.Quartz.ConsoleApp.csproj rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/Abp.Quartz.ConsoleApp.csproj diff --git a/QuartzSample/Abp.Quartz.JobExecuter/AbpQuartzJobExecuterModule.cs b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/AbpQuartzJobExecuterModule.cs similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/AbpQuartzJobExecuterModule.cs rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/AbpQuartzJobExecuterModule.cs diff --git a/QuartzSample/Abp.Quartz.JobExecuter/App.config b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/App.config similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/App.config rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/App.config diff --git a/QuartzSample/Abp.Quartz.JobExecuter/Program.cs b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/Program.cs similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/Program.cs rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/Program.cs diff --git a/QuartzSample/Abp.Quartz.JobExecuter/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/Properties/AssemblyInfo.cs diff --git a/QuartzSample/Abp.Quartz.JobExecuter/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/Abp.Quartz.JobExecuter/packages.config b/dotnet/QuartzSample/Abp.Quartz.JobExecuter/packages.config similarity index 100% rename from QuartzSample/Abp.Quartz.JobExecuter/packages.config rename to dotnet/QuartzSample/Abp.Quartz.JobExecuter/packages.config diff --git a/QuartzSample/Abp.Quartz/Abp.Quartz.csproj b/dotnet/QuartzSample/Abp.Quartz/Abp.Quartz.csproj similarity index 100% rename from QuartzSample/Abp.Quartz/Abp.Quartz.csproj rename to dotnet/QuartzSample/Abp.Quartz/Abp.Quartz.csproj diff --git a/QuartzSample/Abp.Quartz/Configuration/AbpQuartzConfigurationExtensions.cs b/dotnet/QuartzSample/Abp.Quartz/Configuration/AbpQuartzConfigurationExtensions.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Configuration/AbpQuartzConfigurationExtensions.cs rename to dotnet/QuartzSample/Abp.Quartz/Configuration/AbpQuartzConfigurationExtensions.cs diff --git a/QuartzSample/Abp.Quartz/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/Abp.Quartz/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/Abp.Quartz/Properties/AssemblyInfo.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/AbpQuartzJobListener.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/AbpQuartzJobListener.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/AbpQuartzJobListener.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/AbpQuartzJobListener.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/AbpQuartzModule.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/AbpQuartzModule.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/AbpQuartzModule.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/AbpQuartzModule.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/AbpQuartzWindsorFactory.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/Configuration/AbpQuartzConfiguration.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/Configuration/IAbpQuartzConfiguration.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/IQuartzScheduleJobManager.cs diff --git a/QuartzSample/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs b/dotnet/QuartzSample/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs similarity index 100% rename from QuartzSample/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs rename to dotnet/QuartzSample/Abp.Quartz/Quartz/QuartzScheduleJobManager.cs diff --git a/QuartzSample/Abp.Quartz/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/Abp.Quartz/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/Abp.Quartz/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/Abp.Quartz/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/Abp.Quartz/packages.config b/dotnet/QuartzSample/Abp.Quartz/packages.config similarity index 100% rename from QuartzSample/Abp.Quartz/packages.config rename to dotnet/QuartzSample/Abp.Quartz/packages.config diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/AbpQuartzTask.GoodbyeJob.csproj diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJob.cs diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/GoodbyeJobModule.cs diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/Properties/AssemblyInfo.cs diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/app.config b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/app.config similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/app.config rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/app.config diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/AbpQuartzTask.GoodbyeJob/packages.config b/dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/packages.config similarity index 100% rename from QuartzSample/AbpQuartzTask.GoodbyeJob/packages.config rename to dotnet/QuartzSample/AbpQuartzTask.GoodbyeJob/packages.config diff --git a/QuartzSample/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/AbpQuartzTask.HelloJob.csproj diff --git a/QuartzSample/AbpQuartzTask.HelloJob/HelloJob.cs b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/HelloJob.cs similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/HelloJob.cs rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/HelloJob.cs diff --git a/QuartzSample/AbpQuartzTask.HelloJob/HelloJobModule.cs b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/HelloJobModule.cs similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/HelloJobModule.cs rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/HelloJobModule.cs diff --git a/QuartzSample/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/Properties/AssemblyInfo.cs diff --git a/QuartzSample/AbpQuartzTask.HelloJob/app.config b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/app.config similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/app.config rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/app.config diff --git a/QuartzSample/AbpQuartzTask.HelloJob/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/AbpQuartzTask.HelloJob/packages.config b/dotnet/QuartzSample/AbpQuartzTask.HelloJob/packages.config similarity index 100% rename from QuartzSample/AbpQuartzTask.HelloJob/packages.config rename to dotnet/QuartzSample/AbpQuartzTask.HelloJob/packages.config diff --git a/QuartzSample/QuartzCore/App.config b/dotnet/QuartzSample/QuartzCore/App.config similarity index 100% rename from QuartzSample/QuartzCore/App.config rename to dotnet/QuartzSample/QuartzCore/App.config diff --git a/QuartzSample/QuartzCore/Dependency/IocManager.cs b/dotnet/QuartzSample/QuartzCore/Dependency/IocManager.cs similarity index 100% rename from QuartzSample/QuartzCore/Dependency/IocManager.cs rename to dotnet/QuartzSample/QuartzCore/Dependency/IocManager.cs diff --git a/QuartzSample/QuartzCore/Dependency/JobModuleBase.cs b/dotnet/QuartzSample/QuartzCore/Dependency/JobModuleBase.cs similarity index 100% rename from QuartzSample/QuartzCore/Dependency/JobModuleBase.cs rename to dotnet/QuartzSample/QuartzCore/Dependency/JobModuleBase.cs diff --git a/QuartzSample/QuartzCore/Dependency/LifeStyle.cs b/dotnet/QuartzSample/QuartzCore/Dependency/LifeStyle.cs similarity index 100% rename from QuartzSample/QuartzCore/Dependency/LifeStyle.cs rename to dotnet/QuartzSample/QuartzCore/Dependency/LifeStyle.cs diff --git a/QuartzSample/QuartzCore/Dependency/QuartzWindsorFactory.cs b/dotnet/QuartzSample/QuartzCore/Dependency/QuartzWindsorFactory.cs similarity index 100% rename from QuartzSample/QuartzCore/Dependency/QuartzWindsorFactory.cs rename to dotnet/QuartzSample/QuartzCore/Dependency/QuartzWindsorFactory.cs diff --git a/QuartzSample/QuartzCore/NLog.config b/dotnet/QuartzSample/QuartzCore/NLog.config similarity index 100% rename from QuartzSample/QuartzCore/NLog.config rename to dotnet/QuartzSample/QuartzCore/NLog.config diff --git a/QuartzSample/QuartzCore/Program.cs b/dotnet/QuartzSample/QuartzCore/Program.cs similarity index 100% rename from QuartzSample/QuartzCore/Program.cs rename to dotnet/QuartzSample/QuartzCore/Program.cs diff --git a/QuartzSample/QuartzCore/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/QuartzCore/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/QuartzCore/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/QuartzCore/Properties/AssemblyInfo.cs diff --git a/QuartzSample/QuartzCore/Quartz/IPayflexJob.cs b/dotnet/QuartzSample/QuartzCore/Quartz/IPayflexJob.cs similarity index 100% rename from QuartzSample/QuartzCore/Quartz/IPayflexJob.cs rename to dotnet/QuartzSample/QuartzCore/Quartz/IPayflexJob.cs diff --git a/QuartzSample/QuartzCore/Quartz/JobBase.cs b/dotnet/QuartzSample/QuartzCore/Quartz/JobBase.cs similarity index 100% rename from QuartzSample/QuartzCore/Quartz/JobBase.cs rename to dotnet/QuartzSample/QuartzCore/Quartz/JobBase.cs diff --git a/QuartzSample/QuartzCore/Quartz/JobListener.cs b/dotnet/QuartzSample/QuartzCore/Quartz/JobListener.cs similarity index 100% rename from QuartzSample/QuartzCore/Quartz/JobListener.cs rename to dotnet/QuartzSample/QuartzCore/Quartz/JobListener.cs diff --git a/QuartzSample/QuartzCore/Quartz/ReflectionExtensions.cs b/dotnet/QuartzSample/QuartzCore/Quartz/ReflectionExtensions.cs similarity index 100% rename from QuartzSample/QuartzCore/Quartz/ReflectionExtensions.cs rename to dotnet/QuartzSample/QuartzCore/Quartz/ReflectionExtensions.cs diff --git a/QuartzSample/QuartzCore/QuartzCore.csproj b/dotnet/QuartzSample/QuartzCore/QuartzCore.csproj similarity index 100% rename from QuartzSample/QuartzCore/QuartzCore.csproj rename to dotnet/QuartzSample/QuartzCore/QuartzCore.csproj diff --git a/QuartzSample/QuartzCore/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/QuartzCore/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/QuartzCore/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/QuartzCore/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/QuartzCore/packages.config b/dotnet/QuartzSample/QuartzCore/packages.config similarity index 100% rename from QuartzSample/QuartzCore/packages.config rename to dotnet/QuartzSample/QuartzCore/packages.config diff --git a/QuartzSample/QuartzSample.sln b/dotnet/QuartzSample/QuartzSample.sln similarity index 100% rename from QuartzSample/QuartzSample.sln rename to dotnet/QuartzSample/QuartzSample.sln diff --git a/QuartzSample/QuartzTask.GoodbyJob/GoodByeJobModule.cs b/dotnet/QuartzSample/QuartzTask.GoodbyJob/GoodByeJobModule.cs similarity index 100% rename from QuartzSample/QuartzTask.GoodbyJob/GoodByeJobModule.cs rename to dotnet/QuartzSample/QuartzTask.GoodbyJob/GoodByeJobModule.cs diff --git a/QuartzSample/QuartzTask.GoodbyJob/GoodbyeJob.cs b/dotnet/QuartzSample/QuartzTask.GoodbyJob/GoodbyeJob.cs similarity index 100% rename from QuartzSample/QuartzTask.GoodbyJob/GoodbyeJob.cs rename to dotnet/QuartzSample/QuartzTask.GoodbyJob/GoodbyeJob.cs diff --git a/QuartzSample/QuartzTask.GoodbyJob/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/QuartzTask.GoodbyJob/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/QuartzTask.GoodbyJob/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/QuartzTask.GoodbyJob/Properties/AssemblyInfo.cs diff --git a/QuartzSample/QuartzTask.GoodbyJob/QuartzTask.GoodbyeJob.csproj b/dotnet/QuartzSample/QuartzTask.GoodbyJob/QuartzTask.GoodbyeJob.csproj similarity index 100% rename from QuartzSample/QuartzTask.GoodbyJob/QuartzTask.GoodbyeJob.csproj rename to dotnet/QuartzSample/QuartzTask.GoodbyJob/QuartzTask.GoodbyeJob.csproj diff --git a/QuartzSample/QuartzTask.GoodbyJob/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/QuartzTask.GoodbyJob/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/QuartzTask.GoodbyJob/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/QuartzTask.GoodbyJob/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/QuartzTask.GoodbyJob/packages.config b/dotnet/QuartzSample/QuartzTask.GoodbyJob/packages.config similarity index 100% rename from QuartzSample/QuartzTask.GoodbyJob/packages.config rename to dotnet/QuartzSample/QuartzTask.GoodbyJob/packages.config diff --git a/QuartzSample/QuartzTask.HelloJob/Dummy/Dummy.cs b/dotnet/QuartzSample/QuartzTask.HelloJob/Dummy/Dummy.cs similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/Dummy/Dummy.cs rename to dotnet/QuartzSample/QuartzTask.HelloJob/Dummy/Dummy.cs diff --git a/QuartzSample/QuartzTask.HelloJob/Dummy/IDummy.cs b/dotnet/QuartzSample/QuartzTask.HelloJob/Dummy/IDummy.cs similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/Dummy/IDummy.cs rename to dotnet/QuartzSample/QuartzTask.HelloJob/Dummy/IDummy.cs diff --git a/QuartzSample/QuartzTask.HelloJob/HelloJob.cs b/dotnet/QuartzSample/QuartzTask.HelloJob/HelloJob.cs similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/HelloJob.cs rename to dotnet/QuartzSample/QuartzTask.HelloJob/HelloJob.cs diff --git a/QuartzSample/QuartzTask.HelloJob/HelloJobModule.cs b/dotnet/QuartzSample/QuartzTask.HelloJob/HelloJobModule.cs similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/HelloJobModule.cs rename to dotnet/QuartzSample/QuartzTask.HelloJob/HelloJobModule.cs diff --git a/QuartzSample/QuartzTask.HelloJob/Properties/AssemblyInfo.cs b/dotnet/QuartzSample/QuartzTask.HelloJob/Properties/AssemblyInfo.cs similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/Properties/AssemblyInfo.cs rename to dotnet/QuartzSample/QuartzTask.HelloJob/Properties/AssemblyInfo.cs diff --git a/QuartzSample/QuartzTask.HelloJob/QuartzTask.HelloJob.csproj b/dotnet/QuartzSample/QuartzTask.HelloJob/QuartzTask.HelloJob.csproj similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/QuartzTask.HelloJob.csproj rename to dotnet/QuartzSample/QuartzTask.HelloJob/QuartzTask.HelloJob.csproj diff --git a/QuartzSample/QuartzTask.HelloJob/app.config b/dotnet/QuartzSample/QuartzTask.HelloJob/app.config similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/app.config rename to dotnet/QuartzSample/QuartzTask.HelloJob/app.config diff --git a/QuartzSample/QuartzTask.HelloJob/job_scheduling_data_2_0.xsd b/dotnet/QuartzSample/QuartzTask.HelloJob/job_scheduling_data_2_0.xsd similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/job_scheduling_data_2_0.xsd rename to dotnet/QuartzSample/QuartzTask.HelloJob/job_scheduling_data_2_0.xsd diff --git a/QuartzSample/QuartzTask.HelloJob/packages.config b/dotnet/QuartzSample/QuartzTask.HelloJob/packages.config similarity index 100% rename from QuartzSample/QuartzTask.HelloJob/packages.config rename to dotnet/QuartzSample/QuartzTask.HelloJob/packages.config diff --git a/SampleAbpApplication/SampleAbpApplication.sln b/dotnet/SampleAbpApplication/SampleAbpApplication.sln similarity index 100% rename from SampleAbpApplication/SampleAbpApplication.sln rename to dotnet/SampleAbpApplication/SampleAbpApplication.sln diff --git a/SampleAbpApplication/global.json b/dotnet/SampleAbpApplication/global.json similarity index 100% rename from SampleAbpApplication/global.json rename to dotnet/SampleAbpApplication/global.json diff --git a/SampleAbpApplication/src/SampleAbpApplication/DbContexes/AnimalDbContext.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/DbContexes/AnimalDbContext.cs similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/DbContexes/AnimalDbContext.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/DbContexes/AnimalDbContext.cs diff --git a/SampleAbpApplication/src/SampleAbpApplication/DbContexes/PersonDbContext.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/DbContexes/PersonDbContext.cs similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/DbContexes/PersonDbContext.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/DbContexes/PersonDbContext.cs diff --git a/SampleAbpApplication/src/SampleAbpApplication/Entities/Animal.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/Entities/Animal.cs similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/Entities/Animal.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/Entities/Animal.cs diff --git a/SampleAbpApplication/src/SampleAbpApplication/Entities/Person.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/Entities/Person.cs similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/Entities/Person.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/Entities/Person.cs diff --git a/SampleAbpApplication/src/SampleAbpApplication/Program.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/Program.cs similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/Program.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/Program.cs diff --git a/SampleAbpApplication/src/SampleAbpApplication/Properties/AssemblyInfo.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/Properties/AssemblyInfo.cs similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/Properties/AssemblyInfo.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/Properties/AssemblyInfo.cs diff --git a/SampleAbpApplication/src/SampleAbpApplication/SampleAbpApplication.xproj b/dotnet/SampleAbpApplication/src/SampleAbpApplication/SampleAbpApplication.xproj similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/SampleAbpApplication.xproj rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/SampleAbpApplication.xproj diff --git a/SampleAbpApplication/src/SampleAbpApplication/SampleApplicationModule.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/SampleApplicationModule.cs similarity index 56% rename from SampleAbpApplication/src/SampleAbpApplication/SampleApplicationModule.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/SampleApplicationModule.cs index 395404e..2d18b45 100644 --- a/SampleAbpApplication/src/SampleAbpApplication/SampleApplicationModule.cs +++ b/dotnet/SampleAbpApplication/src/SampleAbpApplication/SampleApplicationModule.cs @@ -1,25 +1,19 @@ using System.Reflection; using Abp; -using Abp.Configuration.Startup; -using Abp.Dependency; +using Abp.Dapper; using Abp.EntityFramework; -using Abp.EntityFramework.Uow; using Abp.Modules; namespace SampleAbpApplication { [DependsOn( typeof(AbpEntityFrameworkModule), - typeof(AbpKernelModule) + typeof(AbpKernelModule), + typeof(AbpDapperModule) )] public class SampleApplicationModule : AbpModule { - public override void PreInitialize() - { - Configuration.ReplaceService(DependencyLifeStyle.Transient); - } - public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); diff --git a/SampleAbpApplication/src/SampleAbpApplication/SomeDomainService.cs b/dotnet/SampleAbpApplication/src/SampleAbpApplication/SomeDomainService.cs similarity index 76% rename from SampleAbpApplication/src/SampleAbpApplication/SomeDomainService.cs rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/SomeDomainService.cs index ace89ec..b322ba0 100644 --- a/SampleAbpApplication/src/SampleAbpApplication/SomeDomainService.cs +++ b/dotnet/SampleAbpApplication/src/SampleAbpApplication/SomeDomainService.cs @@ -1,7 +1,11 @@ -using Abp.Dependency; +using System.Linq; + +using Abp.Dapper.Dapper.Repositories; +using Abp.Dependency; using Abp.Domain.Repositories; using Abp.Domain.Uow; using Abp.EntityFramework; +using Abp.EntityFramework.Extensions; using SampleAbpApplication.DbContexes; using SampleAbpApplication.Entities; @@ -12,6 +16,7 @@ public class SomeDomainService : ITransientDependency { private readonly IDbContextProvider _animalDbContextProvider; private readonly IRepository _animalRepository; + private readonly IDapperRepository _personDapperRepository; private readonly IRepository _personRepository; private readonly IUnitOfWorkManager _unitOfWorkManager; @@ -19,12 +24,14 @@ public SomeDomainService( IUnitOfWorkManager unitOfWorkManager, IRepository personRepository, IRepository animalRepository, - IDbContextProvider animalDbContextProvider) + IDbContextProvider animalDbContextProvider, + IDapperRepository personDapperRepository) { _unitOfWorkManager = unitOfWorkManager; _personRepository = personRepository; _animalRepository = animalRepository; _animalDbContextProvider = animalDbContextProvider; + _personDapperRepository = personDapperRepository; } public void DoSomeStuff() @@ -43,6 +50,10 @@ public void DoSomeStuff() Animal animal = _animalRepository.FirstOrDefault(x => x.Name == "Kuş"); + Person person = _personDapperRepository.Get(1); + + Person anotherPerson = _personRepository.Nolocking(persons => persons.FirstOrDefault(x => x.Name == "Ekmek")); + uow.Complete(); } } diff --git a/SampleAbpApplication/src/SampleAbpApplication/app.config b/dotnet/SampleAbpApplication/src/SampleAbpApplication/app.config similarity index 100% rename from SampleAbpApplication/src/SampleAbpApplication/app.config rename to dotnet/SampleAbpApplication/src/SampleAbpApplication/app.config diff --git a/dotnet/SampleAbpApplication/src/SampleAbpApplication/project.json b/dotnet/SampleAbpApplication/src/SampleAbpApplication/project.json new file mode 100644 index 0000000..38e37f6 --- /dev/null +++ b/dotnet/SampleAbpApplication/src/SampleAbpApplication/project.json @@ -0,0 +1,19 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "emitEntryPoint": true + }, + + "dependencies": { + "Abp": "1.5.0", + "Abp.Dapper": "1.5.0", + "Abp.EntityFramework": "1.5.0", + "EntityFrameworkProfiler.Appender": "4.0.4038" + }, + + "frameworks": { + "net461": { + + } + } +} diff --git a/TextDetector/TextDetector.sln b/dotnet/TextDetector/TextDetector.sln similarity index 100% rename from TextDetector/TextDetector.sln rename to dotnet/TextDetector/TextDetector.sln diff --git a/TextDetector/TextDetector/App.config b/dotnet/TextDetector/TextDetector/App.config similarity index 100% rename from TextDetector/TextDetector/App.config rename to dotnet/TextDetector/TextDetector/App.config diff --git a/TextDetector/TextDetector/Program.cs b/dotnet/TextDetector/TextDetector/Program.cs similarity index 100% rename from TextDetector/TextDetector/Program.cs rename to dotnet/TextDetector/TextDetector/Program.cs diff --git a/TextDetector/TextDetector/Properties/AssemblyInfo.cs b/dotnet/TextDetector/TextDetector/Properties/AssemblyInfo.cs similarity index 100% rename from TextDetector/TextDetector/Properties/AssemblyInfo.cs rename to dotnet/TextDetector/TextDetector/Properties/AssemblyInfo.cs diff --git a/TextDetector/TextDetector/TextDetector.csproj b/dotnet/TextDetector/TextDetector/TextDetector.csproj similarity index 100% rename from TextDetector/TextDetector/TextDetector.csproj rename to dotnet/TextDetector/TextDetector/TextDetector.csproj diff --git a/TextDetector/TextDetector/packages.config b/dotnet/TextDetector/TextDetector/packages.config similarity index 100% rename from TextDetector/TextDetector/packages.config rename to dotnet/TextDetector/TextDetector/packages.config diff --git a/dotnet/cake-build/cake.pptx b/dotnet/cake-build/cake.pptx new file mode 100644 index 0000000..eaadb85 Binary files /dev/null and b/dotnet/cake-build/cake.pptx differ diff --git a/dotnet/cake-build/launch.json b/dotnet/cake-build/launch.json new file mode 100644 index 0000000..7e79711 --- /dev/null +++ b/dotnet/cake-build/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [{ + "name": "Cake: Debug Script", + "type": "coreclr", + "request": "launch", + "program": "${workspaceRoot}/tools/Cake.0.19.5/Cake.exe", + "args": [ + "${workspaceRoot}/build.cake", + "--debug", + "--verbosity=diagnostic", + "--experimental" + ], + "cwd": "${workspaceRoot}", + "stopAtEntry": true, + "externalConsole": false + }] +} \ No newline at end of file diff --git a/jvm/ktor-springboot/.gitignore b/jvm/ktor-springboot/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/jvm/ktor-springboot/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/jvm/ktor-springboot/.idea/.gitignore b/jvm/ktor-springboot/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/jvm/ktor-springboot/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/jvm/ktor-springboot/.idea/codeStyles/Project.xml b/jvm/ktor-springboot/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..919ce1f --- /dev/null +++ b/jvm/ktor-springboot/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/jvm/ktor-springboot/.idea/codeStyles/codeStyleConfig.xml b/jvm/ktor-springboot/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/jvm/ktor-springboot/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/jvm/ktor-springboot/.idea/gradle.xml b/jvm/ktor-springboot/.idea/gradle.xml new file mode 100644 index 0000000..14746e7 --- /dev/null +++ b/jvm/ktor-springboot/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/jvm/ktor-springboot/.idea/kotlinc.xml b/jvm/ktor-springboot/.idea/kotlinc.xml new file mode 100644 index 0000000..8d81632 --- /dev/null +++ b/jvm/ktor-springboot/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/jvm/ktor-springboot/.idea/misc.xml b/jvm/ktor-springboot/.idea/misc.xml new file mode 100644 index 0000000..5cd9a10 --- /dev/null +++ b/jvm/ktor-springboot/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/jvm/ktor-springboot/build.gradle.kts b/jvm/ktor-springboot/build.gradle.kts new file mode 100644 index 0000000..4bc3cd9 --- /dev/null +++ b/jvm/ktor-springboot/build.gradle.kts @@ -0,0 +1,32 @@ +plugins { + kotlin("jvm") version libs.versions.kotlin.get() + id(libs.plugins.spring.kotlin.get().pluginId) version libs.versions.kotlin.get() + alias(libs.plugins.spring.boot) + alias(libs.plugins.spring.dependency.management) + application +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(libs.ktor.server.netty) + implementation(libs.ktor.server.content.negotiation) + implementation(libs.ktor.server.jackson) + implementation(libs.spring.boot.starter.webflux) + implementation(libs.arrow.suspendapp) + implementation(libs.arrow.fx.coroutines) + annotationProcessor(libs.spring.boot.configuration.processor) +} + +application { + mainClass.set("org.example.Main.ExampleApp") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(21) +} \ No newline at end of file diff --git a/jvm/ktor-springboot/gradle.properties b/jvm/ktor-springboot/gradle.properties new file mode 100644 index 0000000..7fc6f1f --- /dev/null +++ b/jvm/ktor-springboot/gradle.properties @@ -0,0 +1 @@ +kotlin.code.style=official diff --git a/jvm/ktor-springboot/gradle/libs.versions.toml b/jvm/ktor-springboot/gradle/libs.versions.toml new file mode 100644 index 0000000..cd7ab90 --- /dev/null +++ b/jvm/ktor-springboot/gradle/libs.versions.toml @@ -0,0 +1,23 @@ +[versions] +kotlin = "1.9.22" +ktor = "2.3.7" +spring-boot = "3.1.2" +spring = "6.1.0" +arrow = "1.2.1" + +[libraries] +ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" } +ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" } +ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" } +ktor-server-jackson = { module = "io.ktor:ktor-serialization-jackson", version.ref = "ktor" } +spring-boot-starter-webflux = { module = "org.springframework.boot:spring-boot-starter-webflux", version.ref = "spring-boot" } +spring-context = { module = "org.springframework:spring-context", version.ref = "spring" } +spring-boot-configuration-processor = { module = "org.springframework.boot:spring-boot-configuration-processor", version.ref = "spring-boot" } +arrow-suspendapp = { module = "io.arrow-kt:suspendapp", version = "0.4.0" } +arrow-fx-coroutines = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" } + + +[plugins] +spring-kotlin = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } +spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" } +spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.4" } \ No newline at end of file diff --git a/jvm/ktor-springboot/gradle/wrapper/gradle-wrapper.jar b/jvm/ktor-springboot/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/jvm/ktor-springboot/gradle/wrapper/gradle-wrapper.jar differ diff --git a/jvm/ktor-springboot/gradle/wrapper/gradle-wrapper.properties b/jvm/ktor-springboot/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..4cac070 --- /dev/null +++ b/jvm/ktor-springboot/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Jan 22 23:21:43 CET 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/jvm/ktor-springboot/gradlew b/jvm/ktor-springboot/gradlew new file mode 100755 index 0000000..1b6c787 --- /dev/null +++ b/jvm/ktor-springboot/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/jvm/ktor-springboot/gradlew.bat b/jvm/ktor-springboot/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/jvm/ktor-springboot/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/jvm/ktor-springboot/settings.gradle.kts b/jvm/ktor-springboot/settings.gradle.kts new file mode 100644 index 0000000..2fdd87e --- /dev/null +++ b/jvm/ktor-springboot/settings.gradle.kts @@ -0,0 +1,5 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" +} +rootProject.name = "ktor-springboot" + diff --git a/jvm/ktor-springboot/src/main/kotlin/Configuration.kt b/jvm/ktor-springboot/src/main/kotlin/Configuration.kt new file mode 100644 index 0000000..cf81adf --- /dev/null +++ b/jvm/ktor-springboot/src/main/kotlin/Configuration.kt @@ -0,0 +1,63 @@ +package org.example + +import io.ktor.server.application.* +import io.ktor.server.config.* +import org.springframework.beans.factory.FactoryBean +import org.springframework.core.convert.converter.Converter +import org.springframework.core.env.PropertySource + +/** + * A [PropertySource] for a Spring Container for Ktor applications. + * + * @param name The name of the property source. + * @param source The [ApplicationConfig] to use for the configuration. + */ +class KtorPropertySource(name: String, source: ApplicationConfig) : PropertySource(name, source) { + override fun getProperty(path: String): Any? { + try { + return source.config(path) + } catch (e: Exception) {} + try { + return source.configList(path) + } catch (e: Exception) {} + try { + return source.property(path) + } catch (e: Exception) {} + return null + } +} + +/** + * A [Converter] that converts an instance of [ApplicationConfigValue] to a string. + */ +object KtorApplicationConfigValueStringConverter : Converter { + override fun convert(source: ApplicationConfigValue): String? = source.getString() +} + +/** + * A [Converter] that converts an instance of [ApplicationConfigValue] to a list of strings. + */ +object KtorApplicationConfigValueListConverter : Converter> { + override fun convert(source: ApplicationConfigValue): List = source.getList() +} + +/** + * A [FactoryBean] for accessing an [ApplicationConfig] object of the running [Application]. + * + * @property application The Ktor [Application] to read the configuration from. + * @property path The path to the object. + */ +class KtorApplicationConfigFactoryBean( + private val application: Application, + private val path: String? = null +) : FactoryBean { + + override fun getObject(): ApplicationConfig = application.environment.config.let { + if (path != null) + it.config(path) + else + it + } + + override fun getObjectType(): Class<*> = ApplicationConfig::class.java +} \ No newline at end of file diff --git a/jvm/ktor-springboot/src/main/kotlin/Context.kt b/jvm/ktor-springboot/src/main/kotlin/Context.kt new file mode 100644 index 0000000..772d0a5 --- /dev/null +++ b/jvm/ktor-springboot/src/main/kotlin/Context.kt @@ -0,0 +1,70 @@ +package org.example + +import io.ktor.server.application.* +import io.ktor.util.* +import org.springframework.beans.factory.getBean +import org.springframework.context.ApplicationContext +import org.springframework.context.support.GenericApplicationContext +import org.springframework.context.support.registerBean + +/** + * An [AttributeKey] for accessing the Spring [ApplicationContext] through the Ktor [Application]. + */ +internal val SPRING_KEY = AttributeKey("Spring") + +/** + * Register the given [ApplicationContext] to the given Ktor [Application]. + */ +fun Application.register(context: ApplicationContext) { + attributes.put(SPRING_KEY, context) +} + +/** + * Return the Spring [ApplicationContext] that is associated with this application. + */ +val Application.applicationContext: ApplicationContext get() = attributes[SPRING_KEY] + +/** + * Inject a bean of the given type into the application. + */ +inline fun Application.inject(): T = applicationContext.getBean() + +/** + * Inject a bean of the name and type into the application. + * + * @param name The name of the bean. + */ +inline fun Application.inject(name: String): T = applicationContext.getBean(name, T::class.java) + +/** + * Inject all beans of a given type into the application. + */ +inline fun Application.injectAll(): List = + applicationContext.getBeansOfType(T::class.java).values.toList() + +/** + * Configure the Spring [GenericApplicationContext] for the given Ktor [Application]. + */ +fun GenericApplicationContext.configure(application: Application) { + // Add Ktor configuration to Spring property sources + environment.conversionService.addConverter(KtorApplicationConfigValueListConverter) + environment.conversionService.addConverter(KtorApplicationConfigValueStringConverter) + environment.propertySources.addFirst(KtorPropertySource("ktor", application.environment.config)) + + // Register the Ktor application to the container + registerBean { application } + + // Associate the context with this application + application.register(this) +} + +/** + * Bootstrap the given Ktor module inside a Spring DI container. + * + * @param application The application to run the module in. + * @param module The module to bootstrap inside the container. + */ +fun GenericApplicationContext.bootstrap(application: Application, module: Application.() -> Unit = {}) { + refresh() + module(application) +} \ No newline at end of file diff --git a/jvm/ktor-springboot/src/main/kotlin/Main.kt b/jvm/ktor-springboot/src/main/kotlin/Main.kt new file mode 100644 index 0000000..510bf6f --- /dev/null +++ b/jvm/ktor-springboot/src/main/kotlin/Main.kt @@ -0,0 +1,56 @@ +package org.example + +import arrow.continuations.SuspendApp +import arrow.fx.coroutines.resourceScope +import io.ktor.server.application.* +import io.ktor.server.engine.* +import io.ktor.server.netty.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import kotlinx.coroutines.awaitCancellation +import org.springframework.boot.* +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.ComponentScan +import org.springframework.stereotype.Component + + +@SpringBootApplication +@ComponentScan +class ExampleApp + +fun main(args: Array) = SuspendApp { + resourceScope { + run(args) + awaitCancellation() + } + +} + +private fun run( + args: Array, + configure: SpringApplication.() -> Unit = {} +) = runApplication(*args) { + webApplicationType = WebApplicationType.NONE + configure() +} + +@Component +class HelloWorldService { + fun helloWorld(): String = "Hello World" +} + +@Component +class KtorApplicationRunner(private val ctx: ApplicationContext) : ApplicationRunner { + override fun run(args: ApplicationArguments?) { + embeddedServer(Netty, port = 8080) { + register(ctx) + routing { + get("/") { + val helloWorldService: HelloWorldService = call.application.inject() + call.respondText(helloWorldService.helloWorld()) + } + } + }.start(wait = false) + } +} \ No newline at end of file diff --git a/jvm/ktor-springboot/src/main/resources/application.yml b/jvm/ktor-springboot/src/main/resources/application.yml new file mode 100644 index 0000000..9704349 --- /dev/null +++ b/jvm/ktor-springboot/src/main/resources/application.yml @@ -0,0 +1,3 @@ +ktor: + deployment: + port: 8080 \ No newline at end of file diff --git a/presentations/DeveloperSummit_Turkey_2018_05_12/Effective DDD.pdf b/presentations/DeveloperSummit_Turkey_2018_05_12/Effective DDD.pdf new file mode 100644 index 0000000..830c641 Binary files /dev/null and b/presentations/DeveloperSummit_Turkey_2018_05_12/Effective DDD.pdf differ