From e291f691f11a907745f51d410a907aef34e878f8 Mon Sep 17 00:00:00 2001 From: Peter Kurfer Date: Tue, 10 Mar 2020 21:53:04 +0100 Subject: [PATCH] Refactoring - cleanup structure and CI pipeline - Only publish if release with tag --- .../workflows/{dotnetcore.yml => publish.yml} | 18 ++---- .github/workflows/validate.yml | 26 ++++++++ src/tand/Tand.Core.Tests/LogTarget.cs | 20 ++---- src/tand/Tand.Core.Tests/ResolverMock.cs | 27 ++++++++ .../Tand.Core.Tests/Tand.Core.Tests.csproj | 3 +- src/tand/Tand.Core.Tests/TandSample.cs | 48 ++------------ src/tand/Tand.Core.Tests/TandTests.cs | 22 +++++++ .../{ => Models}/CallEnterContext.cs | 2 +- src/tand/Tand.Core/TandProxy.cs | 63 +++++++++++++++---- ...xtensions.DependencyInjection.Tests.csproj | 3 +- .../DependencyResolverProxy.cs | 1 + .../TandServiceExtensions.cs | 4 +- 12 files changed, 148 insertions(+), 89 deletions(-) rename .github/workflows/{dotnetcore.yml => publish.yml} (75%) create mode 100644 .github/workflows/validate.yml create mode 100644 src/tand/Tand.Core.Tests/ResolverMock.cs create mode 100644 src/tand/Tand.Core.Tests/TandTests.cs rename src/tand/Tand.Core/{ => Models}/CallEnterContext.cs (95%) diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/publish.yml similarity index 75% rename from .github/workflows/dotnetcore.yml rename to .github/workflows/publish.yml index 9407f63..70b0c85 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/publish.yml @@ -1,16 +1,11 @@ -name: .NET Core - +name: Publish on: push: - branches: [ master ] - pull_request: - branches: [ master ] - + tags: + - '**' jobs: - build: - + deploy: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v2 - name: Setup .NET Core @@ -20,9 +15,6 @@ jobs: source-url: https://nuget.pkg.github.com/baez90/index.json env: NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} - - name: Build with dotnet - run: dotnet build --configuration Release - working-directory: ./src/tand/ - name: Pack for deploying package run: dotnet pack --configuration Release working-directory: ./src/tand/ @@ -31,4 +23,4 @@ jobs: working-directory: ./src/tand/ - name: Publish DI extensions package run: dotnet nuget push "Tand.Extensions.DependencyInjection/bin/Release/Tand.Extensions.DependencyInjection.0.0.1.nupkg" - working-directory: ./src/tand/ + working-directory: ./src/tand/ \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..7d69b7a --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,26 @@ +name: Validate + +on: + push: + branches: [ '**' ] + pull_request: + branches: [ '**' ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1.4.0 + with: + dotnet-version: 3.1.101 + source-url: https://nuget.pkg.github.com/baez90/index.json + env: + NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Build with dotnet + run: dotnet build --configuration Release + working-directory: ./src/tand/ + - name: Run tests + run: dotnet test --configuration Release --no-build + working-directory: ./src/tand/ diff --git a/src/tand/Tand.Core.Tests/LogTarget.cs b/src/tand/Tand.Core.Tests/LogTarget.cs index fed2ad6..e58ca8f 100644 --- a/src/tand/Tand.Core.Tests/LogTarget.cs +++ b/src/tand/Tand.Core.Tests/LogTarget.cs @@ -5,31 +5,21 @@ namespace Tand.Core.Tests { public class LogTarget : ITandTarget { - private readonly Action _logHandle; + private readonly Action _instanceHandle; - public LogTarget(Action logHandle) + public LogTarget(Action instanceHandle) { - _logHandle = logHandle; + _instanceHandle = instanceHandle; } public void OnEnterMethod(CallEnterContext enterContext) { - _logHandle(enterContext.Instance.ToString()); - foreach (var (name, val) in enterContext.Arguments) - { - _logHandle($"name: {name}, value: {val}"); - } + _instanceHandle(enterContext.Instance); } public void OnLeaveMethod(CallLeaveContext callLeaveContext) { - _logHandle(callLeaveContext.Instance.ToString()); - foreach (var (name, val) in callLeaveContext.Arguments) - { - _logHandle($"name: {name}, value: {val}"); - } - - _logHandle($"result: {callLeaveContext.CallResult}"); + _instanceHandle(callLeaveContext.Instance); } } } \ No newline at end of file diff --git a/src/tand/Tand.Core.Tests/ResolverMock.cs b/src/tand/Tand.Core.Tests/ResolverMock.cs new file mode 100644 index 0000000..907a86c --- /dev/null +++ b/src/tand/Tand.Core.Tests/ResolverMock.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Tand.Core.Tests +{ + internal class ResolverMock : IDependencyResolver + { + + private readonly IDictionary _targets; + + + internal ResolverMock(params object[] targets) + { + _targets = targets.ToDictionary(target => target.GetType(), target => target); + } + + public ITandTarget TargetOfType(Type type) + { + ResolvingCounter++; + return (ITandTarget)_targets[type]; + } + + internal int ResolvingCounter { get; private set; } + + } +} \ No newline at end of file diff --git a/src/tand/Tand.Core.Tests/Tand.Core.Tests.csproj b/src/tand/Tand.Core.Tests/Tand.Core.Tests.csproj index 9930c99..fb93ae4 100644 --- a/src/tand/Tand.Core.Tests/Tand.Core.Tests.csproj +++ b/src/tand/Tand.Core.Tests/Tand.Core.Tests.csproj @@ -2,8 +2,9 @@ netcoreapp3.1 - false + 8 + enable diff --git a/src/tand/Tand.Core.Tests/TandSample.cs b/src/tand/Tand.Core.Tests/TandSample.cs index 3c7567b..9300be4 100644 --- a/src/tand/Tand.Core.Tests/TandSample.cs +++ b/src/tand/Tand.Core.Tests/TandSample.cs @@ -1,55 +1,17 @@ -using System; -using Xunit; -using Xunit.Abstractions; - namespace Tand.Core.Tests { - public class TandTest + + public interface ITandSample { - private readonly ITestOutputHelper _outputHelper; - - public TandTest(ITestOutputHelper outputHelper) - { - _outputHelper = outputHelper; - } - - [Fact] - public void GenerateTand() - { - var tand = new Tand(new SampleResolver(_outputHelper)); - - var sample = tand.DecorateWithTand(new TandSample()); - var result = sample.LogMyParams("Hello, World", 42); - _outputHelper.WriteLine($"Got result: {result}"); - } - } - - - public class SampleResolver : IDependencyResolver - { - private readonly ITestOutputHelper _outputHelper; - - public SampleResolver(ITestOutputHelper outputHelper) - { - _outputHelper = outputHelper; - } - - public ITandTarget TargetOfType(Type type) - { - return new LogTarget(_outputHelper.WriteLine); - } - } - - public interface ITAndSample - { - [Tand(typeof(LogTarget))] + [Tand(typeof(LogTarget))] int LogMyParams(string s, int i); } - public class TandSample : ITAndSample + public class TandSample : ITandSample { private int _counter; + public string ContextSample { get; set; } public int LogMyParams(string s, int i) diff --git a/src/tand/Tand.Core.Tests/TandTests.cs b/src/tand/Tand.Core.Tests/TandTests.cs new file mode 100644 index 0000000..717eeb3 --- /dev/null +++ b/src/tand/Tand.Core.Tests/TandTests.cs @@ -0,0 +1,22 @@ +using Xunit; + +namespace Tand.Core.Tests +{ + public class TandTests + { + + [Fact] + public void GenerateTand() + { + var handleCallCounter = 0; + var resolver = new ResolverMock(new LogTarget(tandSample => handleCallCounter++)); + var tand = new Tand(resolver); + + var sample = tand.DecorateWithTand(new TandSample()); + var result = sample.LogMyParams("Hello, World", 42); + Assert.Equal(1, result); + Assert.Equal(2, handleCallCounter); + Assert.Equal(1, resolver.ResolvingCounter); + } + } +} \ No newline at end of file diff --git a/src/tand/Tand.Core/CallEnterContext.cs b/src/tand/Tand.Core/Models/CallEnterContext.cs similarity index 95% rename from src/tand/Tand.Core/CallEnterContext.cs rename to src/tand/Tand.Core/Models/CallEnterContext.cs index 7810bd2..7fc2b91 100644 --- a/src/tand/Tand.Core/CallEnterContext.cs +++ b/src/tand/Tand.Core/Models/CallEnterContext.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using Tand.Core.Models; -namespace Tand.Core +namespace Tand.Core.Models { public readonly struct CallEnterContext { diff --git a/src/tand/Tand.Core/TandProxy.cs b/src/tand/Tand.Core/TandProxy.cs index 7ca32d4..46499b8 100644 --- a/src/tand/Tand.Core/TandProxy.cs +++ b/src/tand/Tand.Core/TandProxy.cs @@ -10,9 +10,15 @@ namespace Tand.Core public class TandProxy : DispatchProxy { private readonly IDictionary _targetCache; + private readonly Action? _exceptionHandler; - public TandProxy() + public TandProxy() : this(null) { + } + + public TandProxy(Action? exceptionHandler) + { + _exceptionHandler = exceptionHandler; _targetCache = new ConcurrentDictionary(); } @@ -24,25 +30,56 @@ namespace Tand.Core protected override object Invoke(MethodInfo targetMethod, object[] args) { var mappedMethodArgs = CollectArgs(targetMethod, args); - var enterContext = new CallEnterContext(Decorated, mappedMethodArgs); var targets = TargetTypesForMethod(targetMethod); - foreach (var target in targets) - { - target.OnEnterMethod(enterContext); - } + ProcessOnEntering(targets, new CallEnterContext(Decorated, mappedMethodArgs)); + var result = targetMethod.Invoke(Decorated, args); - var leaveContext = new CallLeaveContext(Decorated, mappedMethodArgs, result); - - foreach (var target in targets) - { - target.OnLeaveMethod(leaveContext); - } - + ProcessOnLeaving(targets, new CallLeaveContext(Decorated, mappedMethodArgs, result)); return result; } + protected virtual void OnEnterMethod(ITandTarget target, CallEnterContext callEnterContext) + { + try + { + target.OnEnterMethod(callEnterContext); + } + catch (Exception e) + { + _exceptionHandler?.Invoke(e); + } + } + + protected virtual void OnLeaveMethod(ITandTarget target, CallLeaveContext callLeaveContext) + { + try + { + target.OnLeaveMethod(callLeaveContext); + } + catch (Exception e) + { + _exceptionHandler?.Invoke(e); + } + } + + private void ProcessOnEntering(IEnumerable> targets, CallEnterContext callEnterContext) + { + foreach (var tandTarget in targets) + { + OnEnterMethod(tandTarget, callEnterContext); + } + } + + private void ProcessOnLeaving(IEnumerable> targets, CallLeaveContext callLeaveContext) + { + foreach (var tandTarget in targets) + { + OnLeaveMethod(tandTarget, callLeaveContext); + } + } + private static IDictionary CollectArgs(MethodBase methodInfo, IReadOnlyList argValues) { var result = new Dictionary(); diff --git a/src/tand/Tand.Extensions.DependencyInjection.Tests/Tand.Extensions.DependencyInjection.Tests.csproj b/src/tand/Tand.Extensions.DependencyInjection.Tests/Tand.Extensions.DependencyInjection.Tests.csproj index 627671d..a4bd305 100644 --- a/src/tand/Tand.Extensions.DependencyInjection.Tests/Tand.Extensions.DependencyInjection.Tests.csproj +++ b/src/tand/Tand.Extensions.DependencyInjection.Tests/Tand.Extensions.DependencyInjection.Tests.csproj @@ -2,8 +2,9 @@ netcoreapp3.1 - false + 8 + enable diff --git a/src/tand/Tand.Extensions.DependencyInjection/DependencyResolverProxy.cs b/src/tand/Tand.Extensions.DependencyInjection/DependencyResolverProxy.cs index d3a0a30..a1c02c0 100644 --- a/src/tand/Tand.Extensions.DependencyInjection/DependencyResolverProxy.cs +++ b/src/tand/Tand.Extensions.DependencyInjection/DependencyResolverProxy.cs @@ -1,5 +1,6 @@ using System; using Tand.Core; +using Tand.Core.Models; namespace Tand.Extensions.DependencyInjection { diff --git a/src/tand/Tand.Extensions.DependencyInjection/TandServiceExtensions.cs b/src/tand/Tand.Extensions.DependencyInjection/TandServiceExtensions.cs index cc384a0..ac5aefb 100644 --- a/src/tand/Tand.Extensions.DependencyInjection/TandServiceExtensions.cs +++ b/src/tand/Tand.Extensions.DependencyInjection/TandServiceExtensions.cs @@ -8,7 +8,7 @@ namespace Tand.Extensions.DependencyInjection { public static void AddTand(this IServiceCollection serviceCollection) { - serviceCollection.TryAddSingleton(sp => new Tand.Core.Tand(new DependencyResolverProxy(sp))); + serviceCollection.TryAddSingleton(sp => new Core.Tand(new DependencyResolverProxy(sp))); } public static IServiceCollection AddTandTransient(this IServiceCollection services) @@ -22,7 +22,7 @@ namespace Tand.Extensions.DependencyInjection private static TService GetTandForType(IServiceProvider serviceProvider) where TImplementation : class, TService where TService : class { - var tand = serviceProvider.GetService(); + var tand = serviceProvider.GetService(); var instance = serviceProvider.GetService(); var proxy = tand.DecorateWithTand(instance); return proxy;