Refactoring
- cleanup structure and CI pipeline - Only publish if release with tag
This commit is contained in:
parent
5ec141c801
commit
e291f691f1
12 changed files with 148 additions and 89 deletions
|
@ -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/
|
26
.github/workflows/validate.yml
vendored
Normal file
26
.github/workflows/validate.yml
vendored
Normal file
|
@ -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/
|
|
@ -5,31 +5,21 @@ namespace Tand.Core.Tests
|
|||
{
|
||||
public class LogTarget<T> : ITandTarget<T>
|
||||
{
|
||||
private readonly Action<string> _logHandle;
|
||||
private readonly Action<T> _instanceHandle;
|
||||
|
||||
public LogTarget(Action<string> logHandle)
|
||||
public LogTarget(Action<T> instanceHandle)
|
||||
{
|
||||
_logHandle = logHandle;
|
||||
_instanceHandle = instanceHandle;
|
||||
}
|
||||
|
||||
public void OnEnterMethod(CallEnterContext<T> enterContext)
|
||||
{
|
||||
_logHandle(enterContext.Instance.ToString());
|
||||
foreach (var (name, val) in enterContext.Arguments)
|
||||
{
|
||||
_logHandle($"name: {name}, value: {val}");
|
||||
}
|
||||
_instanceHandle(enterContext.Instance);
|
||||
}
|
||||
|
||||
public void OnLeaveMethod(CallLeaveContext<T> callLeaveContext)
|
||||
{
|
||||
_logHandle(callLeaveContext.Instance.ToString());
|
||||
foreach (var (name, val) in callLeaveContext.Arguments)
|
||||
{
|
||||
_logHandle($"name: {name}, value: {val}");
|
||||
}
|
||||
|
||||
_logHandle($"result: {callLeaveContext.CallResult}");
|
||||
_instanceHandle(callLeaveContext.Instance);
|
||||
}
|
||||
}
|
||||
}
|
27
src/tand/Tand.Core.Tests/ResolverMock.cs
Normal file
27
src/tand/Tand.Core.Tests/ResolverMock.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tand.Core.Tests
|
||||
{
|
||||
internal class ResolverMock : IDependencyResolver
|
||||
{
|
||||
|
||||
private readonly IDictionary<Type, object> _targets;
|
||||
|
||||
|
||||
internal ResolverMock(params object[] targets)
|
||||
{
|
||||
_targets = targets.ToDictionary(target => target.GetType(), target => target);
|
||||
}
|
||||
|
||||
public ITandTarget<T> TargetOfType<T>(Type type)
|
||||
{
|
||||
ResolvingCounter++;
|
||||
return (ITandTarget<T>)_targets[type];
|
||||
}
|
||||
|
||||
internal int ResolvingCounter { get; private set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>8</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -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<ITAndSample, TandSample>(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<T> TargetOfType<T>(Type type)
|
||||
{
|
||||
return new LogTarget<T>(_outputHelper.WriteLine);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ITAndSample
|
||||
{
|
||||
[Tand(typeof(LogTarget<TandSample>))]
|
||||
[Tand(typeof(LogTarget<ITandSample>))]
|
||||
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)
|
||||
|
|
22
src/tand/Tand.Core.Tests/TandTests.cs
Normal file
22
src/tand/Tand.Core.Tests/TandTests.cs
Normal file
|
@ -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<ITandSample>(tandSample => handleCallCounter++));
|
||||
var tand = new Tand(resolver);
|
||||
|
||||
var sample = tand.DecorateWithTand<ITandSample, TandSample>(new TandSample());
|
||||
var result = sample.LogMyParams("Hello, World", 42);
|
||||
Assert.Equal(1, result);
|
||||
Assert.Equal(2, handleCallCounter);
|
||||
Assert.Equal(1, resolver.ResolvingCounter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<T>
|
||||
{
|
|
@ -10,9 +10,15 @@ namespace Tand.Core
|
|||
public class TandProxy<T> : DispatchProxy
|
||||
{
|
||||
private readonly IDictionary<int, Type[]> _targetCache;
|
||||
private readonly Action<Exception>? _exceptionHandler;
|
||||
|
||||
public TandProxy()
|
||||
public TandProxy() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public TandProxy(Action<Exception>? exceptionHandler)
|
||||
{
|
||||
_exceptionHandler = exceptionHandler;
|
||||
_targetCache = new ConcurrentDictionary<int, Type[]>();
|
||||
}
|
||||
|
||||
|
@ -24,25 +30,56 @@ namespace Tand.Core
|
|||
protected override object Invoke(MethodInfo targetMethod, object[] args)
|
||||
{
|
||||
var mappedMethodArgs = CollectArgs(targetMethod, args);
|
||||
var enterContext = new CallEnterContext<T>(Decorated, mappedMethodArgs);
|
||||
var targets = TargetTypesForMethod(targetMethod);
|
||||
foreach (var target in targets)
|
||||
{
|
||||
target.OnEnterMethod(enterContext);
|
||||
}
|
||||
|
||||
ProcessOnEntering(targets, new CallEnterContext<T>(Decorated, mappedMethodArgs));
|
||||
|
||||
var result = targetMethod.Invoke(Decorated, args);
|
||||
|
||||
var leaveContext = new CallLeaveContext<T>(Decorated, mappedMethodArgs, result);
|
||||
|
||||
foreach (var target in targets)
|
||||
{
|
||||
target.OnLeaveMethod(leaveContext);
|
||||
}
|
||||
|
||||
ProcessOnLeaving(targets, new CallLeaveContext<T>(Decorated, mappedMethodArgs, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual void OnEnterMethod(ITandTarget<T> target, CallEnterContext<T> callEnterContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
target.OnEnterMethod(callEnterContext);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_exceptionHandler?.Invoke(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnLeaveMethod(ITandTarget<T> target, CallLeaveContext<T> callLeaveContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
target.OnLeaveMethod(callLeaveContext);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_exceptionHandler?.Invoke(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessOnEntering(IEnumerable<ITandTarget<T>> targets, CallEnterContext<T> callEnterContext)
|
||||
{
|
||||
foreach (var tandTarget in targets)
|
||||
{
|
||||
OnEnterMethod(tandTarget, callEnterContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessOnLeaving(IEnumerable<ITandTarget<T>> targets, CallLeaveContext<T> callLeaveContext)
|
||||
{
|
||||
foreach (var tandTarget in targets)
|
||||
{
|
||||
OnLeaveMethod(tandTarget, callLeaveContext);
|
||||
}
|
||||
}
|
||||
|
||||
private static IDictionary<string, object> CollectArgs(MethodBase methodInfo, IReadOnlyList<object> argValues)
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>8</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Tand.Core;
|
||||
using Tand.Core.Models;
|
||||
|
||||
namespace Tand.Extensions.DependencyInjection
|
||||
{
|
||||
|
|
|
@ -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<TService, TImplementation>(this IServiceCollection services)
|
||||
|
@ -22,7 +22,7 @@ namespace Tand.Extensions.DependencyInjection
|
|||
|
||||
private static TService GetTandForType<TService, TImplementation>(IServiceProvider serviceProvider) where TImplementation : class, TService where TService : class
|
||||
{
|
||||
var tand = serviceProvider.GetService<Tand.Core.Tand>();
|
||||
var tand = serviceProvider.GetService<Core.Tand>();
|
||||
var instance = serviceProvider.GetService<TImplementation>();
|
||||
var proxy = tand.DecorateWithTand<TService, TImplementation>(instance);
|
||||
return proxy;
|
||||
|
|
Loading…
Reference in a new issue