Initial commit
This commit is contained in:
parent
a6a2e64688
commit
64484d4981
26 changed files with 670 additions and 0 deletions
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
###############
|
||||
# folder #
|
||||
###############
|
||||
/**/DROP/
|
||||
/**/TEMP/
|
||||
/**/packages/
|
||||
/**/bin/
|
||||
/**/obj/
|
||||
_site
|
||||
.idea/
|
5
api/.gitignore
vendored
Normal file
5
api/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
###############
|
||||
# temp file #
|
||||
###############
|
||||
*.yml
|
||||
.manifest
|
2
api/index.md
Normal file
2
api/index.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# PLACEHOLDER
|
||||
TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*!
|
1
articles/intro.md
Normal file
1
articles/intro.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Add your introductions here!
|
2
articles/toc.yml
Normal file
2
articles/toc.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
- name: Introduction
|
||||
href: intro.md
|
64
docfx.json
Normal file
64
docfx.json
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"metadata": [
|
||||
{
|
||||
"src": [
|
||||
{
|
||||
"files": [
|
||||
"src/**.csproj"
|
||||
]
|
||||
}
|
||||
],
|
||||
"dest": "api",
|
||||
"disableGitFeatures": false,
|
||||
"disableDefaultFilter": false
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
"content": [
|
||||
{
|
||||
"files": [
|
||||
"api/**.yml",
|
||||
"api/index.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"articles/**.md",
|
||||
"articles/**/toc.yml",
|
||||
"toc.yml",
|
||||
"*.md"
|
||||
]
|
||||
}
|
||||
],
|
||||
"resource": [
|
||||
{
|
||||
"files": [
|
||||
"images/**"
|
||||
]
|
||||
}
|
||||
],
|
||||
"overwrite": [
|
||||
{
|
||||
"files": [
|
||||
"apidoc/**.md"
|
||||
],
|
||||
"exclude": [
|
||||
"obj/**",
|
||||
"_site/**"
|
||||
]
|
||||
}
|
||||
],
|
||||
"dest": "_site",
|
||||
"globalMetadataFiles": [],
|
||||
"fileMetadataFiles": [],
|
||||
"template": [
|
||||
"statictoc"
|
||||
],
|
||||
"postProcessors": [],
|
||||
"markdownEngineName": "markdig",
|
||||
"noLangKeyword": false,
|
||||
"keepFileLink": false,
|
||||
"cleanupCacheHistory": false,
|
||||
"disableGitFeatures": false
|
||||
}
|
||||
}
|
4
index.md
Normal file
4
index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# This is the **HOMEPAGE**.
|
||||
Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files.
|
||||
## Quick Start Notes:
|
||||
1. Add images to the *images* folder if the file is referencing an image.
|
35
src/tand/Tand.Core.Tests/LogTarget.cs
Normal file
35
src/tand/Tand.Core.Tests/LogTarget.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using Tand.Core.Models;
|
||||
|
||||
namespace Tand.Core.Tests
|
||||
{
|
||||
public class LogTarget<T> : ITandTarget<T>
|
||||
{
|
||||
private readonly Action<string> _logHandle;
|
||||
|
||||
public LogTarget(Action<string> logHandle)
|
||||
{
|
||||
_logHandle = logHandle;
|
||||
}
|
||||
|
||||
public void OnEnterMethod(CallEnterContext<T> enterContext)
|
||||
{
|
||||
_logHandle(enterContext.Instance.ToString());
|
||||
foreach (var (name, val) in enterContext.Arguments)
|
||||
{
|
||||
_logHandle($"name: {name}, value: {val}");
|
||||
}
|
||||
}
|
||||
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
20
src/tand/Tand.Core.Tests/Tand.Core.Tests.csproj
Normal file
20
src/tand/Tand.Core.Tests/Tand.Core.Tests.csproj
Normal file
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tand.Core\Tand.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
60
src/tand/Tand.Core.Tests/TandSample.cs
Normal file
60
src/tand/Tand.Core.Tests/TandSample.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Tand.Core.Tests
|
||||
{
|
||||
public class TandTest
|
||||
{
|
||||
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>))]
|
||||
int LogMyParams(string s, int i);
|
||||
}
|
||||
|
||||
public class TandSample : ITAndSample
|
||||
{
|
||||
|
||||
private int _counter;
|
||||
public string ContextSample { get; set; }
|
||||
|
||||
public int LogMyParams(string s, int i)
|
||||
{
|
||||
return ++_counter;
|
||||
}
|
||||
}
|
||||
}
|
23
src/tand/Tand.Core/CallEnterContext.cs
Normal file
23
src/tand/Tand.Core/CallEnterContext.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Tand.Core.Models;
|
||||
|
||||
namespace Tand.Core
|
||||
{
|
||||
public readonly struct CallEnterContext<T>
|
||||
{
|
||||
private readonly IDictionary<string, object> _methodArgs;
|
||||
|
||||
public CallEnterContext(T instance, IDictionary<string, object> args)
|
||||
{
|
||||
Instance = instance;
|
||||
_methodArgs = args;
|
||||
}
|
||||
|
||||
public T Instance { get; }
|
||||
|
||||
public object? this[string argName] => _methodArgs.ContainsKey(argName) ? _methodArgs[argName] : null;
|
||||
|
||||
public IEnumerable<MethodArgument> Arguments => _methodArgs.Select(kv => new MethodArgument(kv.Key, kv.Value));
|
||||
}
|
||||
}
|
9
src/tand/Tand.Core/IDependencyResolver.cs
Normal file
9
src/tand/Tand.Core/IDependencyResolver.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Tand.Core
|
||||
{
|
||||
public interface IDependencyResolver
|
||||
{
|
||||
ITandTarget<T> TargetOfType<T>(Type type);
|
||||
}
|
||||
}
|
11
src/tand/Tand.Core/ITandTarget.cs
Normal file
11
src/tand/Tand.Core/ITandTarget.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using Tand.Core.Models;
|
||||
|
||||
namespace Tand.Core
|
||||
{
|
||||
public interface ITandTarget<T>
|
||||
{
|
||||
void OnEnterMethod(CallEnterContext<T> enterContext);
|
||||
|
||||
void OnLeaveMethod(CallLeaveContext<T> leaveContext);
|
||||
}
|
||||
}
|
29
src/tand/Tand.Core/Models/CallLeaveContext.cs
Normal file
29
src/tand/Tand.Core/Models/CallLeaveContext.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tand.Core.Models
|
||||
{
|
||||
public readonly struct CallLeaveContext<T>
|
||||
{
|
||||
private readonly IDictionary<string, object> _methodArgs;
|
||||
|
||||
public CallLeaveContext(
|
||||
T instance,
|
||||
IDictionary<string, object> args,
|
||||
object callResult
|
||||
)
|
||||
{
|
||||
Instance = instance;
|
||||
_methodArgs = args;
|
||||
CallResult = callResult;
|
||||
}
|
||||
|
||||
public T Instance { get; }
|
||||
|
||||
public object CallResult { get; }
|
||||
|
||||
public object? this[string argName] => _methodArgs.ContainsKey(argName) ? _methodArgs[argName] : null;
|
||||
|
||||
public IEnumerable<MethodArgument> Arguments => _methodArgs.Select(kv => new MethodArgument(kv.Key, kv.Value));
|
||||
}
|
||||
}
|
21
src/tand/Tand.Core/Models/MethodArgument.cs
Normal file
21
src/tand/Tand.Core/Models/MethodArgument.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace Tand.Core.Models
|
||||
{
|
||||
public readonly struct MethodArgument
|
||||
{
|
||||
public MethodArgument(string name, object value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public object Value { get; }
|
||||
|
||||
public void Deconstruct(out string name, out object value)
|
||||
{
|
||||
name = Name;
|
||||
value = Value;
|
||||
}
|
||||
}
|
||||
}
|
9
src/tand/Tand.Core/Tand.Core.csproj
Normal file
9
src/tand/Tand.Core/Tand.Core.csproj
Normal file
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>8</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
38
src/tand/Tand.Core/Tand.cs
Normal file
38
src/tand/Tand.Core/Tand.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System.Reflection;
|
||||
|
||||
namespace Tand.Core
|
||||
{
|
||||
public class Tand
|
||||
{
|
||||
private readonly IDependencyResolver _dependencyResolver;
|
||||
|
||||
public Tand(IDependencyResolver dependencyResolver)
|
||||
{
|
||||
_dependencyResolver = dependencyResolver;
|
||||
}
|
||||
|
||||
public TService DecorateWithTand<TService, TImplementation>(TImplementation toBeDecorated)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
{
|
||||
var proxy = DispatchProxy.Create<TService, TandProxy<TService>>();
|
||||
InitProxy<TService, TImplementation>(proxy, toBeDecorated);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
private void InitProxy<TService, TImplementation>(object proxyObj, TService toBeDecorated)
|
||||
{
|
||||
var proxy = proxyObj switch
|
||||
{
|
||||
TandProxy<TService> tp => tp,
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (proxy == null) return;
|
||||
|
||||
proxy.Decorated = toBeDecorated;
|
||||
proxy.ImplementationType = typeof(TImplementation);
|
||||
proxy.DependencyResolver = _dependencyResolver;
|
||||
}
|
||||
}
|
||||
}
|
16
src/tand/Tand.Core/TandAttribute.cs
Normal file
16
src/tand/Tand.Core/TandAttribute.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace Tand.Core
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class TandAttribute : Attribute
|
||||
{
|
||||
|
||||
public TandAttribute(Type targetType)
|
||||
{
|
||||
TargetType = targetType;
|
||||
}
|
||||
|
||||
public Type TargetType { get; }
|
||||
}
|
||||
}
|
73
src/tand/Tand.Core/TandProxy.cs
Normal file
73
src/tand/Tand.Core/TandProxy.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Tand.Core.Models;
|
||||
|
||||
namespace Tand.Core
|
||||
{
|
||||
public class TandProxy<T> : DispatchProxy
|
||||
{
|
||||
private readonly IDictionary<int, Type[]> _targetCache;
|
||||
|
||||
public TandProxy()
|
||||
{
|
||||
_targetCache = new ConcurrentDictionary<int, Type[]>();
|
||||
}
|
||||
|
||||
public Type ImplementationType { get; set; }
|
||||
public T Decorated { private get; set; }
|
||||
|
||||
public IDependencyResolver DependencyResolver { get; set; }
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
var result = targetMethod.Invoke(Decorated, args);
|
||||
|
||||
var leaveContext = new CallLeaveContext<T>(Decorated, mappedMethodArgs, result);
|
||||
|
||||
foreach (var target in targets)
|
||||
{
|
||||
target.OnLeaveMethod(leaveContext);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IDictionary<string, object> CollectArgs(MethodBase methodInfo, IReadOnlyList<object> argValues)
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
var parameters = methodInfo.GetParameters();
|
||||
for (var i = 0; i < parameters.Length && i < argValues.Count; i++)
|
||||
{
|
||||
result.Add(parameters[i].Name, argValues[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private ICollection<ITandTarget<T>> TargetTypesForMethod(MethodInfo methodInfo)
|
||||
{
|
||||
var hash = methodInfo.GetHashCode();
|
||||
if (!_targetCache.ContainsKey(hash))
|
||||
{
|
||||
_targetCache[hash] = methodInfo.GetCustomAttributes<TandAttribute>()
|
||||
.Select(attr => attr.TargetType)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return _targetCache[hash]
|
||||
.Select(type => DependencyResolver.TargetOfType<T>(type))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tand.Extensions.DependencyInjection\Tand.Extensions.DependencyInjection.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Tand.Core;
|
||||
using Tand.Core.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace Tand.Extensions.DependencyInjection.Tests
|
||||
{
|
||||
public class TandServiceExtensionsTests
|
||||
{
|
||||
public const string Greeting = "Hello, World!";
|
||||
|
||||
[Fact]
|
||||
public void RegisterService_RegisterSampleService_SuccessfullyResolve()
|
||||
{
|
||||
var calledOnEnter = false;
|
||||
var calledOnExit = false;
|
||||
var servides = new ServiceCollection();
|
||||
servides.AddTand();
|
||||
servides.AddSingleton(new TestDecorator(_ => { calledOnEnter = true;}, _ => { calledOnExit = true;}));
|
||||
servides.AddTandTransient<ISampleService, SampleServiceImpl>();
|
||||
var provider = servides.BuildServiceProvider();
|
||||
|
||||
var sampleService = provider.GetService<ISampleService>();
|
||||
Assert.NotNull(sampleService);
|
||||
var result = sampleService.Greet();
|
||||
|
||||
Assert.Equal(Greeting, result);
|
||||
Assert.True(calledOnEnter);
|
||||
Assert.True(calledOnExit);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestDecorator : ITandTarget<ISampleService>
|
||||
{
|
||||
private readonly Action<CallEnterContext<ISampleService>> _onEnterHandle;
|
||||
private readonly Action<CallLeaveContext<ISampleService>> _onLeaveHandle;
|
||||
|
||||
public TestDecorator(Action<CallEnterContext<ISampleService>> onEnterHandle, Action<CallLeaveContext<ISampleService>> onLeaveHandle)
|
||||
{
|
||||
_onEnterHandle = onEnterHandle;
|
||||
_onLeaveHandle = onLeaveHandle;
|
||||
}
|
||||
|
||||
public void OnEnterMethod(CallEnterContext<ISampleService> enterContext) => _onEnterHandle(enterContext);
|
||||
|
||||
public void OnLeaveMethod(CallLeaveContext<ISampleService> leaveContext) => _onLeaveHandle(leaveContext);
|
||||
}
|
||||
|
||||
public interface ISampleService
|
||||
{
|
||||
[Tand(typeof(TestDecorator))]
|
||||
string Greet();
|
||||
}
|
||||
|
||||
public class SampleServiceImpl : ISampleService
|
||||
{
|
||||
public string Greet() => TandServiceExtensionsTests.Greeting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using Tand.Core;
|
||||
|
||||
namespace Tand.Extensions.DependencyInjection
|
||||
{
|
||||
public class DependencyResolverProxy : IDependencyResolver
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public DependencyResolverProxy(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public ITandTarget<T> TargetOfType<T>(Type type) => _serviceProvider.GetService(type) switch
|
||||
{
|
||||
ITandTarget<T> target => target,
|
||||
_ => throw new ArgumentException()
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tand.Core\Tand.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace Tand.Extensions.DependencyInjection
|
||||
{
|
||||
public static class TandServiceExtensions
|
||||
{
|
||||
public static void AddTand(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.TryAddSingleton(sp => new Tand.Core.Tand(new DependencyResolverProxy(sp)));
|
||||
}
|
||||
|
||||
public static IServiceCollection AddTandTransient<TService, TImplementation>(this IServiceCollection services)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
{
|
||||
services.AddTransient<TImplementation>();
|
||||
services.AddTransient(GetTandForType<TService, TImplementation>);
|
||||
return services;
|
||||
}
|
||||
|
||||
private static TService GetTandForType<TService, TImplementation>(IServiceProvider serviceProvider) where TImplementation : class, TService where TService : class
|
||||
{
|
||||
var tand = serviceProvider.GetService<Tand.Core.Tand>();
|
||||
var instance = serviceProvider.GetService<TImplementation>();
|
||||
var proxy = tand.DecorateWithTand<TService, TImplementation>(instance);
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
}
|
86
src/tand/Tand.sln
Normal file
86
src/tand/Tand.sln
Normal file
|
@ -0,0 +1,86 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26124.0
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tand.Core", "Tand.Core\Tand.Core.csproj", "{994166B2-862B-451B-B3E5-B2797EFF7022}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4A0DFFF5-7BB2-481A-BB0F-152D89823F48}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C51CA370-A0C7-4229-90FA-ADF7B51DE021}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tand.Core.Tests", "Tand.Core.Tests\Tand.Core.Tests.csproj", "{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tand.Extensions.DependencyInjection", "Tand.Extensions.DependencyInjection\Tand.Extensions.DependencyInjection.csproj", "{C535C043-7A0E-4F17-89E4-493E7805CFAC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tand.Extensions.DependencyInjection.Tests", "Tand.Extensions.DependencyInjection.Tests\Tand.Extensions.DependencyInjection.Tests.csproj", "{D1287B4D-319A-4D7A-BB5B-93C4E8320480}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Release|x64.Build.0 = Release|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{994166B2-862B-451B-B3E5-B2797EFF7022} = {4A0DFFF5-7BB2-481A-BB0F-152D89823F48}
|
||||
{7CFEE412-6D6A-407B-9FAE-1640F74D98E7} = {C51CA370-A0C7-4229-90FA-ADF7B51DE021}
|
||||
{C535C043-7A0E-4F17-89E4-493E7805CFAC} = {4A0DFFF5-7BB2-481A-BB0F-152D89823F48}
|
||||
{D1287B4D-319A-4D7A-BB5B-93C4E8320480} = {C51CA370-A0C7-4229-90FA-ADF7B51DE021}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
5
toc.yml
Normal file
5
toc.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- name: Articles
|
||||
href: articles/
|
||||
- name: Api Documentation
|
||||
href: api/
|
||||
homepage: api/index.md
|
Loading…
Reference in a new issue