@@ -0,0 +1,51 @@ | |||||
*.doc diff=astextplain | |||||
*.DOC diff=astextplain | |||||
*.docx diff=astextplain | |||||
*.DOCX diff=astextplain | |||||
*.dot diff=astextplain | |||||
*.DOT diff=astextplain | |||||
*.pdf diff=astextplain | |||||
*.PDF diff=astextplain | |||||
*.rtf diff=astextplain | |||||
*.RTF diff=astextplain | |||||
*.jpg binary | |||||
*.png binary | |||||
*.gif binary | |||||
*.cs text=auto diff=csharp | |||||
*.vb text=auto | |||||
*.resx text=auto | |||||
*.c text=auto | |||||
*.cpp text=auto | |||||
*.cxx text=auto | |||||
*.h text=auto | |||||
*.hxx text=auto | |||||
*.py text=auto | |||||
*.rb text=auto | |||||
*.java text=auto | |||||
*.html text=auto | |||||
*.htm text=auto | |||||
*.css text=auto | |||||
*.scss text=auto | |||||
*.sass text=auto | |||||
*.less text=auto | |||||
*.js text=auto | |||||
*.lisp text=auto | |||||
*.clj text=auto | |||||
*.sql text=auto | |||||
*.php text=auto | |||||
*.lua text=auto | |||||
*.m text=auto | |||||
*.asm text=auto | |||||
*.erl text=auto | |||||
*.fs text=auto | |||||
*.fsx text=auto | |||||
*.hs text=auto | |||||
*.csproj text=auto | |||||
*.vbproj text=auto | |||||
*.fsproj text=auto | |||||
*.dbproj text=auto | |||||
*.sln text=auto eol=crlf | |||||
*.sh eol=lf |
@@ -0,0 +1,30 @@ | |||||
[Oo]bj/ | |||||
[Bb]in/ | |||||
TestResults/ | |||||
.nuget/ | |||||
_ReSharper.*/ | |||||
packages/ | |||||
artifacts/ | |||||
PublishProfiles/ | |||||
*.user | |||||
*.suo | |||||
*.cache | |||||
*.docstates | |||||
_ReSharper.* | |||||
nuget.exe | |||||
*net45.csproj | |||||
*net451.csproj | |||||
*k10.csproj | |||||
*.psess | |||||
*.vsp | |||||
*.pidb | |||||
*.userprefs | |||||
*DS_Store | |||||
*.ncrunchsolution | |||||
*.*sdf | |||||
*.ipch | |||||
*.sln.ide | |||||
project.lock.json | |||||
.vs | |||||
.build/ | |||||
.testPublish/ |
@@ -0,0 +1,34 @@ | |||||
| |||||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio 14 | |||||
VisualStudioVersion = 14.0.25420.1 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | |||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9B2AE124-6636-4DE9-83A3-70360DABD0C4}" | |||||
EndProject | |||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}" | |||||
EndProject | |||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{57A8A8E5-5715-41BF-A0A6-46B819933FBC}" | |||||
ProjectSection(SolutionItems) = preProject | |||||
global.json = global.json | |||||
EndProjectSection | |||||
EndProject | |||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Cap.Consistency", "src\Cap.Consistency\Cap.Consistency.xproj", "{E8AF8611-0EA4-4B19-BC48-87C57A87DC66}" | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|Any CPU = Debug|Any CPU | |||||
Release|Any CPU = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{E8AF8611-0EA4-4B19-BC48-87C57A87DC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{E8AF8611-0EA4-4B19-BC48-87C57A87DC66}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{E8AF8611-0EA4-4B19-BC48-87C57A87DC66}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{E8AF8611-0EA4-4B19-BC48-87C57A87DC66}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
GlobalSection(NestedProjects) = preSolution | |||||
{E8AF8611-0EA4-4B19-BC48-87C57A87DC66} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} | |||||
EndGlobalSection | |||||
EndGlobal |
@@ -0,0 +1,21 @@ | |||||
MIT License | |||||
Copyright (c) 2016 Savorboard | |||||
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. |
@@ -0,0 +1,3 @@ | |||||
# kafkabus | |||||
a .net core message consistence middleware , and now developing... |
@@ -0,0 +1,3 @@ | |||||
{ | |||||
"projects": ["src"] | |||||
} |
@@ -0,0 +1,30 @@ | |||||
using Cap.Consistency; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | |||||
namespace Microsoft.AspNetCore.Builder | |||||
{ | |||||
/// <summary> | |||||
/// KafkaConsostence extensions for <see cref="IApplicationBuilder"/> | |||||
/// </summary> | |||||
public static class BuilderExtensions | |||||
{ | |||||
/// <summary> | |||||
/// Enables KafkaConsistence for the current application | |||||
/// </summary> | |||||
/// <param name="app">The <see cref="IApplicationBuilder"/> instance this method extends.</param> | |||||
/// <returns>The <see cref="IApplicationBuilder"/> instance this method extends.</returns> | |||||
public static IApplicationBuilder UseKafkaConsistence(this IApplicationBuilder app) { | |||||
if (app == null) { | |||||
throw new ArgumentNullException(nameof(app)); | |||||
} | |||||
var marker = app.ApplicationServices.GetService<KafkaConsistenceMarkerService>(); | |||||
if (marker == null) { | |||||
throw new InvalidOperationException("AddKafkaConsistence must be called on the service collection."); | |||||
} | |||||
return app; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,21 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | |||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> | |||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | |||||
</PropertyGroup> | |||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> | |||||
<PropertyGroup Label="Globals"> | |||||
<ProjectGuid>e8af8611-0ea4-4b19-bc48-87c57a87dc66</ProjectGuid> | |||||
<RootNamespace>KafkaConsistence</RootNamespace> | |||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> | |||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | |||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |||||
</PropertyGroup> | |||||
<PropertyGroup> | |||||
<SchemaVersion>2.0</SchemaVersion> | |||||
</PropertyGroup> | |||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | |||||
</Project> |
@@ -0,0 +1,48 @@ | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using System; | |||||
namespace Cap.Consistency | |||||
{ | |||||
/// <summary> | |||||
/// Creates a new instance of <see cref="ConsistenceBuilder"/>. | |||||
/// </summary> | |||||
/// <param name="message">The <see cref="Type"/> to use for the message.</param> | |||||
/// <param name="services">The <see cref="IServiceCollection"/> to attach to.</param> | |||||
public class ConsistenceBuilder | |||||
{ | |||||
public ConsistenceBuilder(Type message, IServiceCollection service) { | |||||
MessageType = message; | |||||
Services = service; | |||||
} | |||||
/// <summary> | |||||
/// Gets the <see cref="IServiceCollection"/> services are attached to. | |||||
/// </summary> | |||||
/// <value> | |||||
/// The <see cref="IServiceCollection"/> services are attached to. | |||||
/// </value> | |||||
public IServiceCollection Services { get; private set; } | |||||
/// <summary> | |||||
/// Gets the <see cref="Type"/> used for messages. | |||||
/// </summary> | |||||
/// <value> | |||||
/// The <see cref="Type"/> used for messages. | |||||
/// </value> | |||||
public Type MessageType { get; private set; } | |||||
/// <summary> | |||||
/// Adds a <see cref="IRoleStore{TRole}"/> for the <seealso cref="RoleType"/>. | |||||
/// </summary> | |||||
/// <typeparam name="T">The role type held in the store.</typeparam> | |||||
/// <returns>The current <see cref="IdentityBuilder"/> instance.</returns> | |||||
public virtual ConsistenceBuilder AddMessageStore<T>() where T : class { | |||||
return AddScoped(typeof(IConsistentMessageStore<>).MakeGenericType(MessageType), typeof(T)); | |||||
} | |||||
private ConsistenceBuilder AddScoped(Type serviceType, Type concreteType) { | |||||
Services.AddScoped(serviceType, concreteType); | |||||
return this; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,147 @@ | |||||
using Microsoft.AspNetCore.Http; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using System; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace Cap.Consistency | |||||
{ | |||||
/// <summary> | |||||
/// Provides the APIs for managing message in a persistence store. | |||||
/// </summary> | |||||
/// <typeparam name="TMessage">The type encapsulating a message.</typeparam> | |||||
public class ConsistentMessageManager<TMessage> : IDisposable where TMessage : class | |||||
{ | |||||
private bool _disposed; | |||||
private readonly HttpContext _context; | |||||
private CancellationToken CancellationToken => _context?.RequestAborted ?? CancellationToken.None; | |||||
/// <summary> | |||||
/// Constructs a new instance of <see cref="ConsistentMessageManager{TMessage}"/>. | |||||
/// </summary> | |||||
/// <param name="store">The persistence store the manager will operate over.</param> | |||||
/// <param name="services">The <see cref="IServiceProvider"/> used to resolve services.</param> | |||||
/// <param name="logger">The logger used to log messages, warnings and errors.</param> | |||||
public ConsistentMessageManager(IConsistentMessageStore<TMessage> store, | |||||
IServiceProvider services, | |||||
ILogger<ConsistentMessageManager<TMessage>> logger) { | |||||
if (store == null) { | |||||
throw new ArgumentNullException(nameof(store)); | |||||
} | |||||
Store = store; | |||||
Logger = logger; | |||||
if (services != null) { | |||||
_context = services.GetService<IHttpContextAccessor>()?.HttpContext; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Gets or sets the persistence store the manager operates over. | |||||
/// </summary> | |||||
/// <value>The persistence store the manager operates over.</value> | |||||
protected internal IConsistentMessageStore<TMessage> Store { get; set; } | |||||
/// <summary> | |||||
/// Gets the <see cref="ILogger"/> used to log messages from the manager. | |||||
/// </summary> | |||||
/// <value> | |||||
/// The <see cref="ILogger"/> used to log messages from the manager. | |||||
/// </value> | |||||
protected internal virtual ILogger Logger { get; set; } | |||||
/// <summary> | |||||
/// Creates the specified <paramref name="message"/> in the backing store. | |||||
/// </summary> | |||||
/// <param name="message">The message to create.</param> | |||||
/// <returns> | |||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | |||||
/// of the operation. | |||||
/// </returns> | |||||
public virtual Task<OperateResult> CreateAsync(TMessage message) { | |||||
ThrowIfDisposed(); | |||||
//todo: validation message fileds is correct | |||||
return Store.CreateAsync(message, CancellationToken); | |||||
} | |||||
/// <summary> | |||||
/// Updates the specified <paramref name="message"/> in the backing store. | |||||
/// </summary> | |||||
/// <param name="message">The message to update.</param> | |||||
/// <returns> | |||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | |||||
/// of the operation. | |||||
/// </returns> | |||||
public virtual Task<OperateResult> UpdateMessageAsync(TMessage message) { | |||||
ThrowIfDisposed(); | |||||
//todo: validation message fileds is correct | |||||
return Store.UpdateAsync(message, CancellationToken); | |||||
} | |||||
/// <summary> | |||||
/// Deletes the specified <paramref name="message"/> in the backing store. | |||||
/// </summary> | |||||
/// <param name="message">The message to delete.</param> | |||||
/// <returns> | |||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | |||||
/// of the operation. | |||||
/// </returns> | |||||
public virtual Task<OperateResult> DeleteMessageAsync(TMessage message) { | |||||
ThrowIfDisposed(); | |||||
if (message == null) { | |||||
throw new ArgumentNullException(nameof(message)); | |||||
} | |||||
return Store.DeleteAsync(message, CancellationToken); | |||||
} | |||||
/// <summary> | |||||
/// Finds and returns a message, if any, who has the specified <paramref name="messageId"/>. | |||||
/// </summary> | |||||
/// <param name="userId">The message ID to search for.</param> | |||||
/// <returns> | |||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the user matching the specified <paramref name="messageId"/> if it exists. | |||||
/// </returns> | |||||
public virtual Task<TMessage> FindByIdAsync(string messageId) { | |||||
ThrowIfDisposed(); | |||||
return Store.FindByIdAsync(messageId, CancellationToken); | |||||
} | |||||
/// <summary> | |||||
/// Gets the message identifier for the specified <paramref name="user"/>. | |||||
/// </summary> | |||||
/// <param name="user">The message whose identifier should be retrieved.</param> | |||||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the identifier for the specified <paramref name="message"/>.</returns> | |||||
public virtual async Task<string> GetMessageIdAsync(TMessage message) { | |||||
ThrowIfDisposed(); | |||||
return await Store.GetMessageIdAsync(message, CancellationToken); | |||||
} | |||||
public void Dispose() { | |||||
Dispose(true); | |||||
GC.SuppressFinalize(this); | |||||
} | |||||
/// <summary> | |||||
/// Releases the unmanaged resources used by the message manager and optionally releases the managed resources. | |||||
/// </summary> | |||||
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> | |||||
protected virtual void Dispose(bool disposing) { | |||||
if (disposing && !_disposed) { | |||||
Store.Dispose(); | |||||
_disposed = true; | |||||
} | |||||
} | |||||
protected void ThrowIfDisposed() { | |||||
if (_disposed) { | |||||
throw new ObjectDisposedException(GetType().Name); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,55 @@ | |||||
using System; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace Cap.Consistency | |||||
{ | |||||
/// <summary> | |||||
/// Provides an abstraction for a store which manages kafka consistent message. | |||||
/// </summary> | |||||
/// <typeparam name="TMessage"></typeparam> | |||||
public interface IConsistentMessageStore<TMessage> : IDisposable where TMessage : class | |||||
{ | |||||
/// <summary> | |||||
/// Finds and returns a message, if any, who has the specified <paramref name="messageId"/>. | |||||
/// </summary> | |||||
/// <param name="messageId">The message ID to search for.</param> | |||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||||
/// <returns> | |||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the message matching the specified <paramref name="messageId"/> if it exists. | |||||
/// </returns> | |||||
Task<TMessage> FindByIdAsync(string messageId, CancellationToken cancellationToken); | |||||
/// <summary> | |||||
/// Creates a new message in a store as an asynchronous operation. | |||||
/// </summary> | |||||
/// <param name="message">The message to create in the store.</param> | |||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns> | |||||
Task<OperateResult> CreateAsync(TMessage message, CancellationToken cancellationToken); | |||||
/// <summary> | |||||
/// Updates a message in a store as an asynchronous operation. | |||||
/// </summary> | |||||
/// <param name="message">The message to update in the store.</param> | |||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns> | |||||
Task<OperateResult> UpdateAsync(TMessage message, CancellationToken cancellationToken); | |||||
/// <summary> | |||||
/// Deletes a message from the store as an asynchronous operation. | |||||
/// </summary> | |||||
/// <param name="message">The message to delete in the store.</param> | |||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns> | |||||
Task<OperateResult> DeleteAsync(TMessage message, CancellationToken cancellationToken); | |||||
/// <summary> | |||||
/// Gets the ID for a message from the store as an asynchronous operation. | |||||
/// </summary> | |||||
/// <param name="message">The message whose ID should be returned.</param> | |||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||||
/// <returns>A <see cref="Task{TResult}"/> that contains the ID of the message.</returns> | |||||
Task<string> GetMessageIdAsync(TMessage message, CancellationToken cancellationToken); | |||||
} | |||||
} |
@@ -0,0 +1,7 @@ | |||||
namespace Cap.Consistency | |||||
{ | |||||
/// <summary> | |||||
/// Used to verify KafkaConsistence was called on a ServiceCollection | |||||
/// </summary> | |||||
public class KafkaConsistenceMarkerService { } | |||||
} |
@@ -0,0 +1,76 @@ | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
namespace Cap.Consistency | |||||
{ | |||||
/// <summary> | |||||
/// Represents the result of an consistent message operation. | |||||
/// </summary> | |||||
public class OperateResult | |||||
{ | |||||
private static readonly OperateResult _success = new OperateResult { Succeeded = true }; | |||||
private List<OperateError> _errors = new List<OperateError>(); | |||||
/// <summary> | |||||
/// Flag indicating whether if the operation succeeded or not. | |||||
/// </summary> | |||||
public bool Succeeded { get; set; } | |||||
/// <summary> | |||||
/// An <see cref="IEnumerable{T}"/> of <see cref="OperateError"/>s containing an errors | |||||
/// that occurred during the operation. | |||||
/// </summary> | |||||
/// <value>An <see cref="IEnumerable{T}"/> of <see cref="OperateError"/>s.</value> | |||||
public IEnumerable<OperateError> Errors => _errors; | |||||
/// <summary> | |||||
/// Returns an <see cref="IdentityResult"/> indicating a successful identity operation. | |||||
/// </summary> | |||||
/// <returns>An <see cref="IdentityResult"/> indicating a successful operation.</returns> | |||||
public static OperateResult Success => _success; | |||||
/// <summary> | |||||
/// Creates an <see cref="IdentityResult"/> indicating a failed operation, with a list of <paramref name="errors"/> if applicable. | |||||
/// </summary> | |||||
/// <param name="errors">An optional array of <see cref="IdentityError"/>s which caused the operation to fail.</param> | |||||
/// <returns>An <see cref="IdentityResult"/> indicating a failed operation, with a list of <paramref name="errors"/> if applicable.</returns> | |||||
public static OperateResult Failed(params OperateError[] errors) { | |||||
var result = new OperateResult { Succeeded = false }; | |||||
if (errors != null) { | |||||
result._errors.AddRange(errors); | |||||
} | |||||
return result; | |||||
} | |||||
/// <summary> | |||||
/// Converts the value of the current <see cref="IdentityResult"/> object to its equivalent string representation. | |||||
/// </summary> | |||||
/// <returns>A string representation of the current <see cref="IdentityResult"/> object.</returns> | |||||
/// <remarks> | |||||
/// If the operation was successful the ToString() will return "Succeeded" otherwise it returned | |||||
/// "Failed : " followed by a comma delimited list of error codes from its <see cref="Errors"/> collection, if any. | |||||
/// </remarks> | |||||
public override string ToString() { | |||||
return Succeeded ? | |||||
"Succeeded" : | |||||
string.Format("{0} : {1}", "Failed", string.Join(",", Errors.Select(x => x.Code).ToList())); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Encapsulates an error from the operate subsystem. | |||||
/// </summary> | |||||
public class OperateError | |||||
{ | |||||
/// <summary> | |||||
/// Gets or sets ths code for this error. | |||||
/// </summary> | |||||
public string Code { get; set; } | |||||
/// <summary> | |||||
/// Gets or sets the description for this error. | |||||
/// </summary> | |||||
public string Description { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
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("KafkaConsistence")] | |||||
[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("e8af8611-0ea4-4b19-bc48-87c57a87dc66")] |
@@ -0,0 +1,25 @@ | |||||
using Cap.Consistency; | |||||
using Microsoft.Extensions.DependencyInjection.Extensions; | |||||
namespace Microsoft.Extensions.DependencyInjection | |||||
{ | |||||
/// <summary> | |||||
/// Contains extension methods to <see cref="IServiceCollection"/> for configuring kafka consistence services. | |||||
/// </summary> | |||||
public static class ServiceCollectionExtensions | |||||
{ | |||||
/// <summary> | |||||
/// Adds and configures the consistence services for the consitence. | |||||
/// </summary> | |||||
/// <param name="services">The services available in the application.</param> | |||||
/// <returns>An <see cref="IServiceCollection"/> for application services.</returns> | |||||
public static ConsistenceBuilder AddKafkaConsistence<TMessage>(this IServiceCollection services) | |||||
where TMessage : class { | |||||
services.TryAddSingleton<KafkaConsistenceMarkerService>(); | |||||
return new ConsistenceBuilder(typeof(TMessage), services); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
{ | |||||
"version": "1.0.0-*", | |||||
"dependencies": { | |||||
"Microsoft.AspNetCore.Http.Abstractions": "1.1.0-*", | |||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.1.0", | |||||
"Microsoft.Extensions.Logging.Abstractions": "1.1.0-*", | |||||
"NETStandard.Library": "1.6.1" | |||||
}, | |||||
"frameworks": { | |||||
"netstandard1.6": { | |||||
"imports": "dnxcore50" | |||||
} | |||||
} | |||||
} |