Jinaga.UnitTest
0.2.108
See the version list below for details.
dotnet add package Jinaga.UnitTest --version 0.2.108
NuGet\Install-Package Jinaga.UnitTest -Version 0.2.108
<PackageReference Include="Jinaga.UnitTest" Version="0.2.108" />
paket add Jinaga.UnitTest --version 0.2.108
#r "nuget: Jinaga.UnitTest, 0.2.108"
// Install Jinaga.UnitTest as a Cake Addin #addin nuget:?package=Jinaga.UnitTest&version=0.2.108 // Install Jinaga.UnitTest as a Cake Tool #tool nuget:?package=Jinaga.UnitTest&version=0.2.108
Jinaga.NET
Resilient, reliable data transfer for .NET.
What it Does
In Jinaga, you define a data model in terms of immutable facts. A fact represents an entity, a change to an entity, or a decision that a user or service has made.
In Jinaga.NET, facts are C# record
s.:
[FactType("Corporate.Company")]
record Company(string identifier) {}
[FactType("Corporate.Employee")]
record Employee(Company company, int employeeNumber) {}
When a user or service makes a decision, you will add a fact to the system. This will store it in the local database. It will also update the local UI. And it will publish it so that others can learn about the decision.
var contoso = await j.Fact(new Company("Contoso"));
var jane = await j.Fact(new Employee(contoso, 1));
var bob = await j.Fact(new Employee(contoso, 2));
To query facts, write a specification. Start at a know fact and find all related facts that match that specification.
var employeesOfCompany = Given<Company>.Match((company, facts) =>
from employee in facts.OfType<Employee>()
where employee.company == company
select employee
);
var contosoEmployees = await j.Query(contoso, employeesOfCompany);
A query returns results at a point in time. If you want to keep a user interface up-to-date, you will need to continually watch.
var observer = j.Watch(contoso, employeesOfCompany, o => o
.OnAdded(employee => AddEmployeeComponent(employee))
.OnRemoved(component => RemoveEmployeeComponent(component))
);
Finally, if you want to be notified in real time of new information, just subscribe.
var subscription = j.Subscribe(contoso, employeesOfCompany);
The client will open a persistent connection with the server. The server will notify the client the moment a new employee is hired. Because the client already set up a watch, the new employee will appear on the UI.
Running a Replicator
A Jinaga front end connects to a device called a Replicator. The Jinaga Replicator is a single machine in a network. It stores and shares facts. To get started, create a Replicator of your very own using Docker.
docker pull jinaga/jinaga-replicator
docker create --name my-replicator -p8080:8080 jinaga/jinaga-replicator
docker start my-replicator
This creates and starts a new container called my-replicator
.
The container is listening at port 8080 for commands.
Configure Jinaga to use the replicator:
var j = JinagaClient.Create(); // Defaults to http://localhost:8080/jinaga
Roadmap
Jinaga.NET is co-evolving with Jinaga.JS. Each of these projects has a front end and a back end. Either front end is intended to work with either back end. And the back ends are intended to interconnect to form a decision substrate.
APIs
The primary APIs for Jinaga are:
j.Fact
- Add and publish a factj.Query
- Project the facts matching a specificationj.Watch
- Continually update a projectionj.Subscribe
- Receive continuous updates from peers
The Subscribe
API is not fully implemented in Jinaga.JS, and not implemented yet in Jinaga.NET.
The JS version uses polling rather than the intended mechanism of Web Sockets or HTTP/2 Server Push.
Storage
Jinaga.NET currently has only memory storage, which is packaged with the unit testing library. The next storage solutions to implement are SQLite to support Xamarin mobile apps and PostgreSQL to support Docker deployment. After that, the MS SQL Server implementation will support enterprise solutions that need to keep the journal transactionally consistent with the projection.
The IStore
interface for Jinaga.NET currently includes both Query
and QueryAll
.
The QueryAll
method is more general.
All calls to Query
will be moved over, and then the more specific method will be removed.
Jinaga.JS does not yet have the equivalent of QueryAll
, so that will come later.
Pipelines
The pipeline compiler continues to evolve. I'm using .NET Interactive Notebooks to explore the types of queries that applications will need, and then test drive their implementations. The next pipeline feature to implement is nested specifications.
The pipeline inverter is currently driven by scenarios as well. A future project will be to walk through the proof of query inversion presented in The Art of Immutable Architecture and verify that this pipeline inverter is correct. We will also back port the Jinaga.NET pipeline inverter to Jinaga.JS.
Rules
Authorization rules -- which limit the users who can create facts -- are implemented in Jinaga.JS, but not yet in Jinaga.NET. Distribution rules -- which limit the specifications that a user can query -- are not yet implemented in either.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. 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. |
-
net5.0
- Jinaga (>= 0.2.108)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 118 | 7/16/2024 |
0.12.8 | 87 | 7/14/2024 |
0.12.7 | 95 | 7/14/2024 |
0.12.6 | 88 | 7/13/2024 |
0.12.5 | 126 | 7/7/2024 |
0.12.4 | 113 | 7/6/2024 |
0.12.3 | 102 | 7/3/2024 |
0.12.2 | 108 | 6/29/2024 |
0.12.1 | 95 | 6/9/2024 |
0.12.0 | 133 | 5/26/2024 |
0.11.18 | 110 | 5/18/2024 |
0.11.17 | 130 | 4/19/2024 |
0.11.16 | 130 | 4/14/2024 |
0.11.15 | 140 | 4/9/2024 |
0.11.14 | 116 | 4/7/2024 |
0.11.13 | 117 | 4/7/2024 |
0.11.12 | 131 | 4/7/2024 |
0.11.11 | 138 | 4/1/2024 |
0.11.10 | 152 | 3/31/2024 |
0.11.9 | 127 | 3/30/2024 |
0.11.8 | 111 | 3/30/2024 |
0.11.7 | 140 | 3/29/2024 |
0.11.6 | 124 | 3/24/2024 |
0.11.5 | 163 | 3/13/2024 |
0.11.4 | 211 | 3/6/2024 |
0.11.3 | 204 | 3/1/2024 |
0.11.2 | 152 | 2/29/2024 |
0.11.1 | 233 | 2/19/2024 |
0.11.0 | 189 | 2/16/2024 |
0.10.1 | 214 | 2/15/2024 |
0.10.0 | 269 | 2/11/2024 |
0.9.7 | 251 | 2/10/2024 |
0.9.6 | 250 | 2/8/2024 |
0.9.5 | 292 | 2/2/2024 |
0.9.4 | 228 | 2/1/2024 |
0.9.3 | 253 | 1/31/2024 |
0.9.2 | 285 | 1/24/2024 |
0.9.1 | 272 | 1/20/2024 |
0.9.0 | 315 | 1/19/2024 |
0.8.4 | 539 | 11/17/2023 |
0.8.3 | 426 | 11/11/2023 |
0.8.2 | 415 | 11/2/2023 |
0.8.1 | 429 | 11/1/2023 |
0.7.2 | 459 | 10/19/2023 |
0.7.1 | 486 | 9/21/2023 |
0.7.0 | 536 | 9/12/2023 |
0.6.5 | 581 | 8/29/2023 |
0.6.4 | 563 | 8/26/2023 |
0.6.3 | 499 | 8/26/2023 |
0.6.2 | 538 | 8/19/2023 |
0.6.1 | 516 | 8/19/2023 |
0.6.0 | 523 | 8/17/2023 |
0.5.1 | 533 | 8/16/2023 |
0.5.0 | 541 | 8/12/2023 |
0.4.0 | 566 | 5/28/2023 |
0.3.0 | 697 | 2/12/2023 |
0.2.109 | 797 | 2/5/2023 |
0.2.108 | 922 | 10/18/2022 |
0.2.107 | 998 | 10/15/2022 |
0.2.106 | 1,049 | 10/12/2022 |
0.2.105 | 967 | 10/11/2022 |
0.2.104 | 1,009 | 9/25/2022 |
0.2.103 | 1,064 | 9/25/2022 |
0.2.98 | 1,015 | 9/25/2022 |
0.2.97 | 1,030 | 9/25/2022 |
0.2.24 | 787 | 11/30/2021 |
0.2.23 | 845 | 11/27/2021 |
0.2.22 | 2,517 | 11/27/2021 |
0.2.21 | 3,479 | 11/25/2021 |
0.2.20 | 935 | 11/12/2021 |
0.2.19 | 797 | 11/11/2021 |
0.2.15 | 856 | 11/9/2021 |
0.2.13 | 845 | 11/8/2021 |
0.2.3 | 902 | 11/4/2021 |
0.2.1 | 869 | 11/3/2021 |
0.2.0 | 865 | 11/1/2021 |
0.1.1 | 900 | 9/26/2021 |
0.1.0 | 939 | 9/26/2021 |