@@ -28,4 +28,5 @@ project.lock.json | |||||
.vs | .vs | ||||
.build/ | .build/ | ||||
.testPublish/ | .testPublish/ | ||||
/src/Cap.Consistency/obj/Debug/netstandard1.6 | |||||
obj/ | |||||
bin/ |
@@ -16,6 +16,11 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Cap.Consistency", "src\Cap. | |||||
EndProject | EndProject | ||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Cap.Consistency.Test", "test\Cap.Consistency.Test\Cap.Consistency.Test.xproj", "{3A444CF8-1611-407F-8D32-5D0CDC3DD49D}" | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Cap.Consistency.Test", "test\Cap.Consistency.Test\Cap.Consistency.Test.xproj", "{3A444CF8-1611-407F-8D32-5D0CDC3DD49D}" | ||||
EndProject | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E5A7F49-8E31-4A71-90CC-1DA9AEDA99EE}" | |||||
ProjectSection(SolutionItems) = preProject | |||||
test\Shared\TestConsistencyMessage.cs = test\Shared\TestConsistencyMessage.cs | |||||
EndProjectSection | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
@@ -37,5 +42,6 @@ Global | |||||
GlobalSection(NestedProjects) = preSolution | GlobalSection(NestedProjects) = preSolution | ||||
{E8AF8611-0EA4-4B19-BC48-87C57A87DC66} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} | {E8AF8611-0EA4-4B19-BC48-87C57A87DC66} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} | ||||
{3A444CF8-1611-407F-8D32-5D0CDC3DD49D} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0} | {3A444CF8-1611-407F-8D32-5D0CDC3DD49D} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0} | ||||
{9E5A7F49-8E31-4A71-90CC-1DA9AEDA99EE} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0} | |||||
EndGlobalSection | EndGlobalSection | ||||
EndGlobal | EndGlobal |
@@ -1,5 +1,6 @@ | |||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using System; | using System; | ||||
using System.Reflection; | |||||
namespace Cap.Consistency | namespace Cap.Consistency | ||||
{ | { | ||||
@@ -43,9 +44,28 @@ namespace Cap.Consistency | |||||
return AddScoped(typeof(IConsistencyMessageStore<>).MakeGenericType(MessageType), typeof(T)); | return AddScoped(typeof(IConsistencyMessageStore<>).MakeGenericType(MessageType), typeof(T)); | ||||
} | } | ||||
/// <summary> | |||||
/// Adds a <see cref="ConsistencyMessageManager{TUser}"/> for the <seealso cref="MessageType"/>. | |||||
/// </summary> | |||||
/// <typeparam name="TMessageManager">The type of the message manager to add.</typeparam> | |||||
/// <returns>The current <see cref="ConsistencyBuilder"/> instance.</returns> | |||||
public virtual ConsistencyBuilder AddConsistencyMessageManager<TMessageManager>() where TMessageManager : class { | |||||
var messageManagerType = typeof(ConsistencyMessageManager<>).MakeGenericType(MessageType); | |||||
var customType = typeof(TMessageManager); | |||||
if (messageManagerType == customType || | |||||
!messageManagerType.GetTypeInfo().IsAssignableFrom(customType.GetTypeInfo())) { | |||||
throw new InvalidOperationException($"Type {customType.Name} must be derive from ConsistencyMessageManager<{MessageType.Name}>"); | |||||
} | |||||
Services.AddScoped(customType, services => services.GetRequiredService(messageManagerType)); | |||||
return AddScoped(messageManagerType, customType); | |||||
} | |||||
private ConsistencyBuilder AddScoped(Type serviceType, Type concreteType) { | private ConsistencyBuilder AddScoped(Type serviceType, Type concreteType) { | ||||
Services.AddScoped(serviceType, concreteType); | Services.AddScoped(serviceType, concreteType); | ||||
return this; | return this; | ||||
} | } | ||||
} | } | ||||
} | } |
@@ -5,7 +5,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; | |||||
namespace Microsoft.Extensions.DependencyInjection | namespace Microsoft.Extensions.DependencyInjection | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Contains extension methods to <see cref="IServiceCollection"/> for configuring kafka consistence services. | |||||
/// Contains extension methods to <see cref="IServiceCollection"/> for configuring consistence services. | |||||
/// </summary> | /// </summary> | ||||
public static class ServiceCollectionExtensions | public static class ServiceCollectionExtensions | ||||
{ | { | ||||
@@ -14,10 +14,13 @@ namespace Microsoft.Extensions.DependencyInjection | |||||
/// </summary> | /// </summary> | ||||
/// <param name="services">The services available in the application.</param> | /// <param name="services">The services available in the application.</param> | ||||
/// <returns>An <see cref="IServiceCollection"/> for application services.</returns> | /// <returns>An <see cref="IServiceCollection"/> for application services.</returns> | ||||
public static ConsistencyBuilder AddKafkaConsistence<TMessage>(this IServiceCollection services) | |||||
public static ConsistencyBuilder AddConsistency<TMessage>(this IServiceCollection services) | |||||
where TMessage : class { | where TMessage : class { | ||||
services.TryAddSingleton<ConsistencyMarkerService>(); | services.TryAddSingleton<ConsistencyMarkerService>(); | ||||
services.TryAddScoped<ConsistencyMessageManager<TMessage>, ConsistencyMessageManager<TMessage>>(); | |||||
return new ConsistencyBuilder(typeof(TMessage), services); | return new ConsistencyBuilder(typeof(TMessage), services); | ||||
} | } | ||||
} | } |
@@ -4,7 +4,6 @@ | |||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> | <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> | ||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> | <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> | ||||
<PropertyGroup Label="Globals"> | <PropertyGroup Label="Globals"> | ||||
<ProjectGuid>3a444cf8-1611-407f-8d32-5d0cdc3dd49d</ProjectGuid> | <ProjectGuid>3a444cf8-1611-407f-8d32-5d0cdc3dd49d</ProjectGuid> | ||||
@@ -13,9 +12,11 @@ | |||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | ||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion> | <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup> | <PropertyGroup> | ||||
<SchemaVersion>2.0</SchemaVersion> | <SchemaVersion>2.0</SchemaVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> | |||||
</ItemGroup> | |||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | ||||
</Project> | |||||
</Project> |
@@ -1,14 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Cap.Consistency.Test | |||||
{ | |||||
public class Class1 | |||||
{ | |||||
public Class1() | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -1,9 +1,12 @@ | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Xunit; | using Xunit; | ||||
using Microsoft.Extensions.Logging; | |||||
using Moq; | |||||
namespace Cap.Consistency.Test | namespace Cap.Consistency.Test | ||||
{ | { | ||||
@@ -11,7 +14,40 @@ namespace Cap.Consistency.Test | |||||
{ | { | ||||
[Fact] | [Fact] | ||||
public void EnsureDefaultServicesDefaultsWithStoreWorks() { | public void EnsureDefaultServicesDefaultsWithStoreWorks() { | ||||
var services = new ServiceCollection().AddTransient<IConsistencyMessageStore<TestConsistencyMessage>, NoopMessageStore>(); | |||||
var services = new ServiceCollection() | |||||
.AddTransient<IConsistencyMessageStore<TestConsistencyMessage>, NoopMessageStore>(); | |||||
services.AddConsistency<TestConsistencyMessage>(); | |||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | |||||
services.AddLogging(); | |||||
var manager = services.BuildServiceProvider() | |||||
.GetRequiredService<ConsistencyMessageManager<TestConsistencyMessage>>(); | |||||
Assert.NotNull(manager); | |||||
} | |||||
[Fact] | |||||
public void AddMessageManagerWithCustomerMannagerReturnsSameInstance() { | |||||
var services = new ServiceCollection() | |||||
.AddTransient<IConsistencyMessageStore<TestConsistencyMessage>, NoopMessageStore>() | |||||
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); | |||||
services.AddLogging(); | |||||
services.AddConsistency<TestConsistencyMessage>() | |||||
.AddConsistencyMessageManager<CustomMessageManager>(); | |||||
var provider = services.BuildServiceProvider(); | |||||
Assert.Same(provider.GetRequiredService<ConsistencyMessageManager<TestConsistencyMessage>>(), | |||||
provider.GetRequiredService<CustomMessageManager>()); | |||||
} | |||||
public class CustomMessageManager : ConsistencyMessageManager<TestConsistencyMessage> | |||||
{ | |||||
public CustomMessageManager() | |||||
: base(new Mock<IConsistencyMessageStore<TestConsistencyMessage>>().Object, null, null) { | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -1,19 +0,0 @@ | |||||
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: AssemblyConfiguration("")] | |||||
[assembly: AssemblyCompany("")] | |||||
[assembly: AssemblyProduct("Cap.Consistency.Test")] | |||||
[assembly: AssemblyTrademark("")] | |||||
// 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("3a444cf8-1611-407f-8d32-5d0cdc3dd49d")] |
@@ -1,10 +1,20 @@ | |||||
{ | |||||
{ | |||||
"version": "1.0.0-*", | "version": "1.0.0-*", | ||||
"buildOptions": { | |||||
"warningsAsErrors": true, | |||||
"compile": { | |||||
"include": "../Shared/TestConsistencyMessage.cs" | |||||
} | |||||
}, | |||||
"dependencies": { | "dependencies": { | ||||
"xunit": "2.2.0-beta4-build3444", | |||||
"dotnet-test-xunit": "2.2.0-preview2-build1029", | |||||
"Cap.Consistency": "1.0.0-*" | |||||
"xunit": "2.2.0-*", | |||||
"Microsoft.AspNetCore.Http": "1.1.0-*", | |||||
"Microsoft.Extensions.DependencyInjection": "1.1.0-*", | |||||
"dotnet-test-xunit": "2.2.0-*", | |||||
"Cap.Consistency": "1.0.0-*", | |||||
"Moq": "4.6.36-*", | |||||
"Microsoft.Extensions.Logging": "1.1.0-*" | |||||
}, | }, | ||||
"frameworks": { | "frameworks": { | ||||
@@ -14,8 +24,7 @@ | |||||
"Microsoft.NETCore.App": { | "Microsoft.NETCore.App": { | ||||
"version": "1.1.0", | "version": "1.1.0", | ||||
"type": "platform" | "type": "platform" | ||||
}, | |||||
//"moq.netcore": "4.4.0-beta8" | |||||
} | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||