Kephas.Messaging 11.1.0-dev.4

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
This is a prerelease version of Kephas.Messaging.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Kephas.Messaging --version 11.1.0-dev.4
NuGet\Install-Package Kephas.Messaging -Version 11.1.0-dev.4
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kephas.Messaging" Version="11.1.0-dev.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Kephas.Messaging --version 11.1.0-dev.4
#r "nuget: Kephas.Messaging, 11.1.0-dev.4"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Kephas.Messaging as a Cake Addin
#addin nuget:?package=Kephas.Messaging&version=11.1.0-dev.4&prerelease

// Install Kephas.Messaging as a Cake Tool
#tool nuget:?package=Kephas.Messaging&version=11.1.0-dev.4&prerelease

Messaging

Application components and services are just pieces in a big puzzle, requiring in most cases to interact and communicate. The simplest interaction is when inside a component the counterpart is identified, either directly or by the means of [[dependency injection|Composition and Dependency Injection]], and the required API method is called. This implies that the consumer knows which provider handles the message and that both components, consumer and provider, live in the same process.

The messaging infrastructure Kephas provides addresses these key issues:

  • The communication may be performed among loosely coupled components. The components communicate through the means of a message, not knowing about each other, not being necessarily in the same process.
  • Two kinds of patterns are supported by default:
    • Request/Response: The requester send a message to be processed and awaits for the response.
    • Publisher/Subscriber: The publisher emits an event for which subscribers are notified when it occurs.
  • The infrastructure may be extended to support other types of patterns, as needed.

To anticipate a little bit, using the messaging infrastructure is as simple as that:

    var message = new PingMessage();
    var pingBack = await messageProcessor.ProcessAsync(message).PreserveThreadContext();
    var serverTime = pingBack.ServerTime;

So, there is no information whatsoever about who processes the message, only the message processor taking the responsibility of carrying this to a good end.

Messages

The message is the content of communication. A message:

  • implements IMessage. This is only a marker interface so that messages may be identified as such and no other kind of objects are communicated.
  • is serializable. This is somehow natural, as the communication may happen inter-processes and even across machines.

Strongly typed and weakly typed messages

The message type plays an important role, as it is used to filter message handlers (more about this in the [[message handlers|Architecture-of-messaging#Message handlers]] section. However, there are so called weakly typed messages, which hold actually a category of messages that for some reason cannot be strongly typed, typically used in distributed scenarios and coming from external sources. These weakly typed messages will provide a name, used for discriminating the message handlers, retrieved as:

  • the MessageName property of the message class -or-
  • the dynamic MessageName property in the case of a dynamic message object.

Events

Events are a special case of messages targeting the Publisher/Subscriber pattern. An event:

  • implements IEvent. This is also a marker interface inheriting from IMessage.

Message handlers

A message handler is an [[application service|Application Services]] processing a message of a given type and, optionally, name.

  • implements the IMessageHandler<TMessage> application service contract.
  • provides the ProcessAsync method where the message handling takes place.
    • ProcessAsync(message: TMessage, context: IMessageProcessingContext, token: CancellationToken): Task<IMessage>
  • (optionally) is annotated with the [MessageName] attribute, to indicate the name of the handled message in case of weakly typed messages.

Typically, a message handler specializes the MessageHandlerBase<TMessage, TResponseMessage> base class, which takes care of basic message type checks and provides an overridable typed ProcessAsync method.

Note: message handlers are NOT singleton application services. This is by design, so that any resources hold during the message processing can be disposed freely at the end. Therefore they can be safely implemented as statefull.

It is the sole responsibility of the message processor to make sure that the handler receives the appropriate messages which it is registered for. The message handler assumes it receives only messages of the declared type and name.

The message processor

The service taking care of message processing is the message processor. It is a [[singleton application service|Application-Services#shared-scope-shared-or-instance-based-services]] which is in charge of selecting the appropriate handler (or handlers) for a particular message, ensuring that that (or those) handlers handle the message, and returning a response. It provides a single method:

  • ProcessAsync(message: IMessage, [context: IMessageProcessingContext], [token: CancellationToken]): Task<IMessage>
    • message: the message to process.
    • context: contextual information related to the particular call. If no processing context is provided, a default one will be created. The processor ensures that the context contains the processor itself, the original message to be processed, and the handler which is at that moment handling the message. This information may be useful in the [[processing behaviors|Architecture-of-messaging#Processing behaviors]], as described in the following sections.

Kephas provides a default implementation, see the [[default message processor|In-Process-messaging#the-defaultmessageprocessor]] for more information about it.

Handler selectors

The typical message bus implementations do not filter the message handlers, leaving them the responsibility of handling or not handling a particular message. In Kephas, this responsibility is delegated to the handler selectors, which decide if and how the handlers are filtered before letting them handle a message. They provide two methods for interaction with the message processor:

  • CanHandle(messageType: Type, messageName: string): boolean: Indicates whether the selector can handle the indicated message type. This is the method by which the selectors are requested to indicate whether they are in charge of providing the handlers for a specific message type and name.
  • GetHandlersFactory(messageType: Type, messageName: string): Func<IEnumerable<IMessageHandler>>: Gets a factory which retrieves the components handling messages of the given type.

EventMessageHandlerSelector

This is a handler selector for [[events|Architecture-of-messaging#Events]]. It returns all the handlers processing the specific event type and name, ordered by their processing priority.

Note: it has the Low processing priority, so that custom code can modify easily the strategy of selecting event handlers.

DefaultMessageHandlerSelector

This is the fallback handler selector for generic messages. It returns a single handler processing the specific message type and name, in the order of override and processing priority. If two or more handlers have the same override and processing priority, an AmbiguousMetchException occurs.

Note: this selector has the lowest processing priority, being the fallback for messages not handled by any other selector.

Processing behaviors

The processing of a message may be intercepted be message processing behaviors, before and after the actual handler invocation. They can do various things, like auditing, authorization checking, or whatever other functionality may be needed. Behaviors are [[singleton application services|Application-Services#shared-scope-shared-or-instance-based-services]], so they should no store any processing information, but use exclusively the processing context for such scenarios. They implement the contract IMessageProcessingBehavior which provides two methods:

  • BeforeProcessAsync(context: IMessageProcessingContext, token: CancellationToken): Task: Interception called before invoking the handler to process the message.
  • AfterProcessAsync(context: IMessageProcessingContext, token: CancellationToken): Task: Interception called after invoking the handler to process the message.

In-process messaging flow

In-Process Messaging

The DefaultMessageProcessor

Kephas provides the DefaultMessageProcessor class, a [[low override priority|Application-Services#override-priority]] message processor. It provides a basic, overridable functionality for processing messages, which should be enough for most cases.

  • It aggregates [[message handler selectors|Architecture-of-messaging#Handler selectors]] and calls them to provide a list of message handlers to process a particular message, in their [[processing priority|Application-Services#processing-priority]] order.
  • It aggregates [[processing filters|Architecture-of-messaging#Processing filters]] and calls them before and after each handler's ProcessAsync call.

Note that the message processor is an in-process service. However, if the handlers themselves go beyond the process boundary it is their sole responsibility and, at the same time, freedom.

The flow of the ProcessAsync implementation is as follows:

  • Resolve the processing filters, ordered by their processing priority.
  • Resolve the handlers, as provided by the handler selectors called in their processing priority order.
    • Question the selectors in the indicated order whether they can provide handlers for the message.
    • The first selector answering with true is delegated to provide the handlers, the rest are ignored.
  • Call each handler to process the message, awaiting for their response.
    • Before calling the handler, the ordered filters are invoked.
    • After calling the handler, the filters are invoked in the inverse order.
  • Returns the response of the last called handler.

Note: if the handler throws an exception, the processing filters are called in the after method. with the exception information set in the context. However, if a filter throws an exception during the processing, it interrupts the flow and the exception is thrown to the caller. This is by design, so that, for example, authorization filters are able to interrupt the processing flow.

Securing the messaging infrastructure

The responsibility of the message processor during execution is to ensure that the provided message gets handled by one or more handlers, and that the behaviors are properly called; however it remains agnostic to the semantics of the message itself. The authorization check is ensured by behaviors:

  • EnsureAuthorizedMessageProcessingBehavior takes the job of ensuring that the handling of the message is authorized.
    • Retrieves the required permissions as specified at message level.
    • Identifies the authorization scope by invoking the [[authorization scope service]].
    • Invokes the [[authorization service]] to authorize the scope for the required permissions.

Securing messages

Messages may be secured by decorating them with the [RequiresPermission] attribute.

Example:

    /// <summary>
    /// Message for importing a hierarchy node.
    /// </summary>
    [RequiresPermission(typeof(IExportImportPermission))]
    public class ImportHierarchyMessage : EntityActionMessage
    {
        // ...
    }
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (13)

Showing the top 5 NuGet packages that depend on Kephas.Messaging:

Package Downloads
Kephas.Messaging.Model The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Provides a modeling API framework for messaging. Provides the model for messaging, including the Message classifier and Messaging scope dimension. Typically used areas and classes/interfaces/services: - IMessageType. - Dimensions: Messaging (area). - AttributedModel: MessagePartAttribute. Kephas Framework ("stone" in aramaic) aims to deliver a solid infrastructure for applications and application ecosystems.

Kephas.Data.Endpoints The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Adds messaging endpoints for data services. The endpoints will work if Kephas.Messaging is referenced and the IMessageProcessor is used for processing the messages. Typically used areas and classes/interfaces/services: - PersistChangesHandler, QueryHandler, DataSourceHandler. Kephas Framework ("stone" in aramaic) aims to deliver a solid infrastructure for applications and application ecosystems.

Kephas.Orchestration The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Provides the infrastructure for orchestrating microservices based on the Kephas Framework. Typically used areas and classes/interfaces/services: - IOrchestrationManager, IRuntimeAppInfo. - Interaction: AppHeartbeatEvent, AppStartedEvent, AppStoppedEvent. - Endpoints: StopAppMessage. Kephas Framework ("stone" in aramaic) aims to deliver a solid infrastructure for applications and application ecosystems.

Kephas.Core.Endpoints The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Adds messaging endpoints for core services. The endpoints wills work if Kephas.Messaging is referenced and the IMessageProcessor is used for processing the messages. Typically used areas and classes/interfaces/services: - EncryptMessage, HashMessage, GetLogLevelMessage, SetLogLevelMessage. Kephas Framework ("stone" in aramaic) aims to deliver a solid infrastructure for applications and application ecosystems.

Kephas.Messaging.Redis The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Provides distributed message routing over Redis using StackExchange.Redis. Typically used areas and classes/interfaces/services: - RedisAppMessageRouter. Kephas Framework ("stone" in aramaic) aims to deliver a solid infrastructure for applications and application ecosystems.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
11.1.0 4,049 4/13/2022
11.1.0-dev.4 138 4/6/2022
11.1.0-dev.3 120 3/30/2022
11.1.0-dev.2 123 3/23/2022
11.1.0-dev.1 119 3/23/2022
11.0.0 3,793 3/11/2022
11.0.0-dev.7 133 3/7/2022
11.0.0-dev.6 125 2/28/2022
11.0.0-dev.5 122 2/26/2022
11.0.0-dev.4 127 2/24/2022
11.0.0-dev.3 123 2/23/2022
11.0.0-dev.2 121 2/18/2022
11.0.0-dev.1 127 2/7/2022
10.3.0 3,823 1/18/2022
10.2.0 2,789 12/3/2021
10.1.0 6,946 11/23/2021
10.1.0-dev.7 188 11/17/2021
10.1.0-dev.6 163 11/16/2021
10.1.0-dev.5 165 11/10/2021
10.1.0-dev.4 175 11/8/2021
10.1.0-dev.3 142 11/8/2021
10.1.0-dev.2 160 11/4/2021
10.1.0-dev.1 153 11/3/2021
10.0.1 2,667 10/16/2021
10.0.0 2,685 10/13/2021
10.0.0-dev.4 146 10/13/2021
10.0.0-dev.3 162 10/11/2021
10.0.0-dev.2 214 10/8/2021
9.3.4 3,058 8/25/2021
9.3.3 2,978 8/25/2021
9.3.2 2,936 8/24/2021
9.3.1 2,844 8/12/2021
9.3.0 2,919 8/12/2021
9.2.0 3,116 6/17/2021
9.1.0 2,997 6/17/2021
9.1.0-dev.9 185 5/26/2021
9.1.0-dev.8 174 5/26/2021
9.1.0-dev.7 182 5/17/2021
9.1.0-dev.6 177 4/28/2021
9.1.0-dev.5 189 4/23/2021
9.1.0-dev.4 183 4/21/2021
9.1.0-dev.3 181 4/17/2021
9.1.0-dev.2 189 4/12/2021
9.1.0-dev.1 180 4/9/2021
9.0.5 3,055 3/31/2021
9.0.4 3,041 3/23/2021
9.0.3 3,026 3/20/2021
9.0.1 2,899 3/18/2021
9.0.0 3,043 3/17/2021
9.0.0-dev.4 177 3/4/2021
9.0.0-dev.3 186 3/1/2021
9.0.0-dev.2 201 2/22/2021
8.4.0 4,481 11/11/2020
8.3.0 3,154 10/28/2020
8.2.0 3,396 10/16/2020
8.1.0 3,467 9/23/2020
8.0.0 6,259 7/1/2020
8.0.0-dev.44 280 6/25/2020
8.0.0-dev.43 275 6/23/2020
8.0.0-dev.42 306 6/22/2020
8.0.0-dev.41 302 6/18/2020
8.0.0-dev.40 264 6/18/2020
8.0.0-dev.39 280 6/15/2020
8.0.0-dev.38 390 6/14/2020
8.0.0-dev.37 252 6/13/2020
8.0.0-dev.36 300 6/13/2020
8.0.0-dev.35 244 6/12/2020
8.0.0-dev.34 285 6/12/2020
8.0.0-dev.33 336 6/10/2020
8.0.0-dev.32 268 6/1/2020
8.0.0-dev.31 289 6/1/2020
8.0.0-dev.30 354 5/30/2020
8.0.0-dev.28 293 5/28/2020
8.0.0-dev.27 282 5/15/2020
8.0.0-dev.26 262 5/14/2020
8.0.0-dev.25 279 5/14/2020
8.0.0-dev.24 261 5/13/2020
8.0.0-dev.23 269 5/13/2020
8.0.0-dev.22 271 5/13/2020
8.0.0-dev.21 275 5/12/2020
8.0.0-dev.20 271 5/12/2020
8.0.0-dev.19 283 5/7/2020
8.0.0-dev.18 279 5/7/2020
8.0.0-dev.17 267 5/6/2020
8.0.0-dev.16 279 5/6/2020
8.0.0-dev.15 278 5/5/2020
8.0.0-dev.14 263 5/5/2020
8.0.0-dev.13 291 5/4/2020
7.6.0-dev.13 291 5/1/2020
7.6.0-dev.12 291 4/30/2020
7.6.0-dev.11 271 4/28/2020
7.6.0-dev.10 269 4/27/2020
7.6.0-dev.9 265 4/24/2020
7.6.0-dev.8 269 4/22/2020
7.6.0-dev.7 266 4/15/2020
7.6.0-dev.6 259 4/15/2020
7.6.0-dev.5 250 4/15/2020
7.6.0-dev.4 381 4/11/2020
7.6.0-dev.3 254 4/10/2020
7.6.0-dev.2 257 4/10/2020
7.6.0-dev.1 345 4/8/2020
7.5.2 2,634 3/20/2020
7.5.1 2,246 3/12/2020
7.5.0 2,944 3/10/2020
7.5.0-dev.18 297 3/5/2020
7.5.0-dev.17 295 3/5/2020
7.5.0-dev.16 315 3/4/2020
7.5.0-dev.15.1 336 3/4/2020
7.5.0-dev.15 253 3/3/2020
7.5.0-dev.14 274 3/3/2020
7.5.0-dev.13 253 2/29/2020
7.5.0-dev.12 384 2/29/2020
7.5.0-dev.10 267 2/25/2020
7.5.0-dev.9 307 2/20/2020
7.5.0-dev.8 331 2/18/2020
7.5.0-dev.7 261 2/18/2020
7.5.0-dev.6 278 2/14/2020
7.5.0-dev.5 294 2/12/2020
7.5.0-dev.4 277 2/11/2020
7.5.0-dev.3 241 2/11/2020
7.5.0-dev.2 391 2/8/2020
7.5.0-dev.1 286 2/7/2020
7.4.2 2,860 2/5/2020
7.4.1 2,702 2/3/2020
7.4.0 2,758 1/31/2020
7.4.0-dev.4 329 1/31/2020
7.4.0-dev.3 311 1/29/2020
7.4.0-dev.2 272 1/28/2020
7.4.0-dev.1 257 1/23/2020
7.3.1 2,709 1/21/2020
7.3.1-preview.7 266 1/21/2020
7.3.1-preview.1 307 1/20/2020
7.3.0 2,645 1/19/2020
7.2.6 2,388 1/18/2020
7.2.5 2,616 12/19/2019
7.2.4 2,343 12/19/2019
7.2.3 2,320 12/16/2019
7.2.2 2,269 12/9/2019
7.2.1 2,520 12/4/2019
7.2.0 2,579 11/26/2019
7.2.0-preview.10 266 11/20/2019
7.2.0-preview.9 275 11/19/2019
7.2.0-preview.8 276 11/18/2019
7.2.0-preview.6 279 11/14/2019
7.2.0-preview.5 278 11/14/2019
7.2.0-preview.4 275 11/14/2019
7.2.0-preview.2 276 11/11/2019
7.2.0-preview.1 284 11/9/2019
7.1.2 1,043 11/7/2019
7.1.1 1,046 11/6/2019
7.1.0 3,050 11/6/2019
7.1.0-preview.8 288 11/5/2019
7.1.0-preview.7 281 11/4/2019
7.1.0-preview.6 274 11/1/2019
7.1.0-preview.5 299 10/31/2019
7.1.0-preview.4 291 10/30/2019
7.1.0-preview.3 281 10/26/2019
7.1.0-preview.2 286 10/25/2019
7.1.0-preview.1 279 10/24/2019
7.0.0 1,641 10/16/2019
7.0.0-rc.41 289 10/15/2019
7.0.0-rc.40 299 10/15/2019
7.0.0-rc.39 282 10/12/2019
7.0.0-rc.38 279 10/11/2019
7.0.0-rc.37 322 10/10/2019
7.0.0-rc.36 286 10/9/2019
7.0.0-rc.35 283 10/8/2019
7.0.0-rc.34 291 10/8/2019
7.0.0-rc.33 278 10/7/2019
7.0.0-rc.32 284 10/5/2019
7.0.0-rc.31 282 10/3/2019
7.0.0-rc.30 291 10/1/2019
7.0.0-rc.28 289 10/1/2019
7.0.0-rc.27 274 9/30/2019
7.0.0-rc.26 283 9/30/2019
7.0.0-rc.25 285 9/27/2019
7.0.0-rc.24 277 9/27/2019
7.0.0-rc.23 277 9/26/2019
7.0.0-rc.22 276 9/25/2019
7.0.0-rc.21 279 9/24/2019
7.0.0-rc.20 282 9/23/2019
7.0.0-rc.19 267 9/20/2019
7.0.0-rc.18.1 282 9/20/2019
7.0.0-rc.18 281 9/20/2019
6.5.0-rc.17 290 9/19/2019
6.5.0-rc.16 308 9/18/2019
6.5.0-rc.15 294 9/18/2019
6.5.0-rc.14.1 286 9/18/2019
6.5.0-rc.14 301 9/17/2019
6.5.0-rc.13 289 9/16/2019
6.5.0-rc.12.2 299 9/13/2019
6.5.0-rc.12.1 287 9/12/2019
6.5.0-rc.12 301 9/12/2019
6.5.0-rc.11 301 9/11/2019
6.5.0-rc.10 287 9/10/2019
6.5.0-rc.9 294 9/9/2019
6.5.0-rc.8 287 9/6/2019
6.5.0-rc.7 288 9/6/2019
6.5.0-rc.6 289 9/6/2019
6.5.0-rc.5 285 9/2/2019
6.5.0-rc.4 303 9/2/2019
6.5.0-rc.3 291 8/30/2019
6.5.0-rc.2 303 8/29/2019
6.5.0-rc.1 302 8/28/2019
6.5.0-beta.5 309 8/28/2019
6.5.0-beta.4 302 8/27/2019
6.0.0 1,725 8/6/2019
6.0.0-rc.7 290 7/19/2019
6.0.0-rc.6 297 6/28/2019
6.0.0-rc.5 294 6/28/2019
6.0.0-rc.4 300 6/25/2019
6.0.0-rc.3 295 6/20/2019
6.0.0-rc.2 305 5/29/2019
6.0.0-rc.1 301 5/28/2019
6.0.0-beta.3 314 4/17/2019
5.3.0-beta.2 295 3/21/2019
5.3.0-beta.1 290 3/20/2019
5.2.0 1,775 3/19/2019
5.1.0 2,053 1/25/2019
5.0.0 2,081 12/21/2018
5.0.0-rc11 1,399 12/14/2018
5.0.0-rc10 1,231 11/16/2018
5.0.0-rc09 1,307 11/1/2018
5.0.0-rc08 1,240 10/31/2018
5.0.0-rc07 1,189 10/31/2018
5.0.0-rc06 1,276 10/30/2018
5.0.0-rc05 1,242 10/29/2018
5.0.0-rc04 1,247 10/29/2018
5.0.0-rc03 1,240 10/26/2018
5.0.0-rc02 1,246 10/25/2018
5.0.0-rc01 1,280 10/12/2018
5.0.0-beta03 1,285 9/21/2018
5.0.0-beta02 1,327 9/10/2018
5.0.0-beta01 1,277 9/7/2018
4.5.1 1,439 8/7/2018
4.5.0 2,553 8/7/2018
4.5.0-rc01 1,334 6/7/2018
4.5.0-beta09 1,298 6/7/2018
4.5.0-beta08 1,531 5/16/2018
4.5.0-beta07 1,308 5/9/2018
4.5.0-beta06 1,364 4/25/2018
4.5.0-beta05 1,518 4/12/2018
4.5.0-beta03 1,437 4/12/2018
4.2.0-beta02 1,421 3/27/2018
4.2.0-beta01 1,427 2/14/2018
4.1.1 1,547 2/1/2018
4.1.0 2,227 1/15/2018
4.1.0-rc10 1,480 12/19/2017
4.1.0-rc09 1,502 12/19/2017
4.1.0-rc08 1,483 12/12/2017
4.1.0-rc07 1,355 12/5/2017
4.1.0-rc06 1,402 12/5/2017
4.1.0-rc05 1,350 12/5/2017
4.1.0-rc03 1,354 12/4/2017
4.1.0-rc02 1,378 12/4/2017
4.1.0-rc01 1,333 12/4/2017
4.1.0-beta09 1,418 12/3/2017
4.1.0-beta08 1,423 11/25/2017
4.1.0-beta07 1,406 11/23/2017
4.1.0-beta06 1,391 11/22/2017
4.1.0-beta05 1,333 11/21/2017
4.1.0-beta04 1,183 11/21/2017
4.1.0-beta03 1,212 11/17/2017
4.1.0-beta02 1,189 11/17/2017
4.1.0-beta01 1,152 11/16/2017
4.0.1-beta01 1,177 11/6/2017
4.0.0 2,652 10/23/2017
4.0.0-rc05 1,350 10/17/2017
4.0.0-rc04 1,341 10/17/2017
4.0.0-rc03 1,366 10/12/2017
4.0.0-rc02 1,333 10/10/2017
4.0.0-rc01 1,345 10/6/2017
4.0.0-beta9 1,304 10/5/2017
4.0.0-beta8 1,349 10/5/2017
4.0.0-beta7 1,416 10/3/2017
4.0.0-beta6 1,329 9/30/2017
4.0.0-beta5 1,328 9/28/2017
4.0.0-beta4 1,377 9/27/2017
4.0.0-beta3 1,326 9/26/2017
4.0.0-beta2 1,364 9/25/2017
4.0.0-beta1 1,347 9/22/2017
3.11.0 1,925 8/18/2017
3.10.1 1,472 8/18/2017
3.10.0 2,305 8/1/2017
3.9.1 1,432 6/23/2017
3.9.0 2,235 6/13/2017
3.8.1 1,730 5/26/2017
3.8.0 1,682 5/26/2017
3.7.0 1,718 5/23/2017
3.6.0 1,686 5/18/2017
3.5.0 1,705 5/15/2017
3.4.0 1,661 5/4/2017
3.3.6 1,441 4/13/2017
3.3.5 1,500 4/12/2017
3.3.1 1,466 4/12/2017
3.3.0 2,297 4/12/2017
3.3.0-preview1 1,252 4/6/2017
3.2.0 1,863 3/27/2017
3.1.0 1,802 3/22/2017
3.1.0-preview4 1,430 3/9/2017
3.1.0-preview3 1,360 12/9/2016
3.1.0-preview2 1,307 12/9/2016
3.1.0-preview1-rc2 1,245 10/31/2016
3.1.0-preview1 1,264 10/28/2016
3.0.9 1,652 10/19/2016
3.0.8 1,544 8/19/2016
3.0.7 1,644 7/12/2016
3.0.7-pre1 1,300 5/18/2016
3.0.6 1,528 5/13/2016
3.0.5 1,869 4/27/2016
3.0.4 1,516 4/14/2016
3.0.0-rc6 1,260 3/29/2016
3.0.0-rc5 1,251 3/24/2016
3.0.0-rc4 1,465 3/21/2016
3.0.0-rc3 1,383 12/22/2015
3.0.0-rc1 1,429 12/21/2015

Please check https://github.com/kephas-software/kephas/releases for the change log.
           Also check the documentation and the samples from https://github.com/kephas-software/kephas/wiki and https://github.com/kephas-software/kephas/tree/master/Samples.