Skip to content

Commit f8f3ffa

Browse files
committed
feat: upgrade to Fusion 6.1.110!
1 parent 0058d45 commit f8f3ffa

File tree

157 files changed

+1454
-2120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+1454
-2120
lines changed

Samples.sln

-7
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "src\Caching\Commo
2929
EndProject
3030
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "src\Caching\Client\Client.csproj", "{C2B70735-480E-4B22-9DF1-8AFAC2C0F634}"
3131
EndProject
32-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "src\Blazor\Client\Client.csproj", "{D6FEBDE1-2FF2-4354-A500-692DD41FA1CA}"
33-
EndProject
3432
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleClient", "src\Blazor\ConsoleClient\ConsoleClient.csproj", "{AB5D5E44-4E90-48BA-BF15-1108C3950550}"
3533
EndProject
3634
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloCart", "src\HelloCart\HelloCart.csproj", "{B36E4A0D-11B7-4F54-8E98-2A9D1C4E6F2E}"
@@ -81,7 +79,6 @@ Global
8179
{C736B632-999C-475A-9556-36CF49E64A00} = {E3EFB37C-E523-44D0-ADC9-DE1257A19125}
8280
{F158690D-69C5-4502-A8CE-E462660BE35F} = {E3EFB37C-E523-44D0-ADC9-DE1257A19125}
8381
{C2B70735-480E-4B22-9DF1-8AFAC2C0F634} = {E3EFB37C-E523-44D0-ADC9-DE1257A19125}
84-
{D6FEBDE1-2FF2-4354-A500-692DD41FA1CA} = {9B29BD3F-7D94-4936-8379-61A2F48259AF}
8582
{AB5D5E44-4E90-48BA-BF15-1108C3950550} = {9B29BD3F-7D94-4936-8379-61A2F48259AF}
8683
{B36E4A0D-11B7-4F54-8E98-2A9D1C4E6F2E} = {B5A8469D-C4BB-4808-8E44-FF4DFCA57BDE}
8784
{60EEDA0D-791F-4195-BE7C-D1E04C66B4FC} = {B5A8469D-C4BB-4808-8E44-FF4DFCA57BDE}
@@ -134,10 +131,6 @@ Global
134131
{C2B70735-480E-4B22-9DF1-8AFAC2C0F634}.Debug|Any CPU.Build.0 = Debug|Any CPU
135132
{C2B70735-480E-4B22-9DF1-8AFAC2C0F634}.Release|Any CPU.ActiveCfg = Release|Any CPU
136133
{C2B70735-480E-4B22-9DF1-8AFAC2C0F634}.Release|Any CPU.Build.0 = Release|Any CPU
137-
{D6FEBDE1-2FF2-4354-A500-692DD41FA1CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
138-
{D6FEBDE1-2FF2-4354-A500-692DD41FA1CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
139-
{D6FEBDE1-2FF2-4354-A500-692DD41FA1CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
140-
{D6FEBDE1-2FF2-4354-A500-692DD41FA1CA}.Release|Any CPU.Build.0 = Release|Any CPU
141134
{AB5D5E44-4E90-48BA-BF15-1108C3950550}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
142135
{AB5D5E44-4E90-48BA-BF15-1108C3950550}.Debug|Any CPU.Build.0 = Debug|Any CPU
143136
{AB5D5E44-4E90-48BA-BF15-1108C3950550}.Release|Any CPU.ActiveCfg = Release|Any CPU

docs/tutorial/Fusion-Cheat-Sheet.md

+9-64
Original file line numberDiff line numberDiff line change
@@ -43,66 +43,25 @@ using (Computed.Invalidate()) {
4343
Register compute service:
4444
```cs
4545
fusion = services.AddFusion(); // services is IServiceCollection
46-
fusion.AddComputeService<ICartService, CartService>();
46+
fusion.AddService<ICartService, CartService>();
4747
```
4848

49-
## Replica Services
49+
## Compute Service Clients
5050

51-
Add controller:
52-
```cs
53-
[Route("api/[controller]/[action]")]
54-
[ApiController, JsonifyErrors, UseDefaultSession]
55-
public class CartController : ControllerBase, ICartService
56-
{
57-
private readonly ICartService _cartService;
58-
private readonly ICommander _commander;
59-
60-
public CartController(ICartService service, ICommander commander)
61-
{
62-
_service = service;
63-
_commander = commander;
64-
}
65-
66-
[HttpGet, Publish]
67-
public Task<List<Order>> GetOrders(long cartId, CancellationToken cancellationToken)
68-
=> _service.GetOrders(cartId, cancellationToken);
69-
}
70-
```
71-
72-
Add client definition:
73-
```cs
74-
[BasePath("cart")]
75-
public interface ICartClientDef
76-
{
77-
[Get(nameof(GetOrders))]
78-
Task<List<Order>> GetOrders(long cartId, CancellationToken cancellationToken);
79-
}
80-
```
81-
82-
Configure Fusion client (this has to be done once in a code that configures client-side `IServiceProvider`):
51+
Configure Fusion RPC client (this has to be done once in a code that configures client-side `IServiceProvider`):
8352
```cs
8453
var baseUri = new Uri("http://localhost:5005");
85-
var apiBaseUri = new Uri($"{baseUri}api/");
8654

8755
var fusion = services.AddFusion();
88-
var fusionClient = fusion.AddRestEaseClient(
89-
client => {
90-
client.ConfigureWebSocketChannel(_ => new() { BaseUri = baseUri });
91-
client.ConfigureHttpClient((_, name, o) => {
92-
var isFusionClient = (name ?? "").StartsWith("Stl.Fusion");
93-
var clientBaseUri = isFusionClient ? baseUri : apiBaseUri;
94-
o.HttpClientActions.Add(httpClient => httpClient.BaseAddress = clientBaseUri);
95-
});
96-
});
56+
fusion.Rpc.AddWebSocketClient(baseUri);
9757
```
9858

99-
Register Replica Service:
59+
Register Compute Service client:
10060
```cs
101-
// After "var fusionClient = ..."
102-
fusionClient.AddReplicaService<ICartService, ICartClientDef>();
61+
fusion.AddClient<ICartService>();
10362
```
10463

105-
Use Replica Service:
64+
Use use it:
10665
```cs
10766
// Just call it the same way you call the original one.
10867
// Any calls that are expected to produce the same result
@@ -166,7 +125,7 @@ Register command handler:
166125
// Nothing is needed for handlers declared inside compute services
167126
```
168127

169-
## Exposing commands to the client via Replica Services
128+
## Exposing commands to the client via Compute Service Clients
170129

171130
Add controller method for the command:
172131
```cs
@@ -182,25 +141,11 @@ public class CartController : ControllerBase, ICartService
182141
=> _commander.Call(command, cancellationToken);
183142
```
184143

185-
Add command handler in the client definition interface:
186-
```cs
187-
public interface ICartClientDef
188-
{
189-
// Always use [Post] and [Body] here
190-
[Post(nameof(UpdateCart))]
191-
Task<Unit> UpdateCart([Body] UpdateCartCommand command, CancellationToken cancellationToken);
192-
```
193-
194-
Register client-side command handler:
195-
```
196-
// Nothing is needed for handlers declared inside replica services
197-
```
198-
199144
## Working with `IComputed`
200145

201146
Capture:
202147
```cs
203-
var computed = await Computed.Capture(ct => service.ComputeMethod(args, ct), cancellationToken);
148+
var computed = await Computed.Capture(() => service.ComputeMethod(args, cancellationToken));
204149
```
205150

206151
Check whether `IComputed` is still consistent:

docs/tutorial/Part00.md

+33-20
Original file line numberDiff line numberDiff line change
@@ -17,49 +17,62 @@ Your should reference:
1717
* `Stl.Fusion.EntityFramework` &ndash; from server-side assemblies,
1818
if you plan to use [EF Core](https://docs.microsoft.com/en-us/ef/).
1919

20-
The full list of Fusion packages:
20+
The list of Fusion packages:
2121

2222
* [Stl](https://www.nuget.org/packages/Stl/) - stands for "ServiceTitan Library"
2323
(yeah, every company needs its own [STL](https://en.wikipedia.org/wiki/Standard_Template_Library)).
2424
It's a collection of relatively isolated abstractions and helpers we couldn't find in BCL.
2525
`Stl` depends on [Castle.Core](https://www.nuget.org/packages/Castle.Core/) & maybe some other
2626
third-party packages.
27-
* [Stl.Net](https://www.nuget.org/packages/Stl.Net/) - depends on `Stl`.
28-
[WebSocketChannel](https://github.com/servicetitan/Stl.Fusion/blob/master/src/Stl.Net/WebSocketChannel.cs)
29-
is currently the only type it contains.
27+
* [Stl.Generators](https://www.nuget.org/packages/Stl.Generators/) - has no dependencies.
28+
It's a Roslyn-based code generation library focused on proxies / call interception.
29+
All Fusion proxies are implemented with it.
3030
* [Stl.Interception](https://www.nuget.org/packages/Stl.Interception/) - depends on `Stl`.
31-
Call interception helpers based on [Castle DynamicProxy](http://www.castleproject.org/projects/dynamicproxy/).
31+
Implements a number of call interception helpers which are used by [Stl.Generators].
32+
* [Stl.Rpc](https://www.nuget.org/packages/Stl.Rpc/) - depends on `Stl`.
33+
An RPC API that Fusion uses to implement Compute Service Clients.
34+
It's probably the fastest RPC implementation over WebSockets that's currently available on .NET - even for plain RPC calls.
35+
* [Stl.Rpc.Server](https://www.nuget.org/packages/Stl.Rpc.Server/) - depends on `Stl.Rpc`.
36+
An implementation of `Stl.Rpc` server for ASP.NET Core, which uses WebSockets.
37+
* [Stl.Rpc.Server.NetFx](https://www.nuget.org/packages/Stl.Rpc.Server.NetFx/) - depends on `Stl.Rpc`.
38+
An implementation of `Stl.Rpc` server for ASP.NET / .NET Framework 4.X, which uses WebSockets.
3239
* [Stl.CommandR](https://www.nuget.org/packages/Stl.CommandR/) - depends on `Stl` and `Stl.Interception`.
3340
CommandR is "[MediatR](hhttps://github.com/jbogard/MediatR) on steroids" designed to support
3441
not only interface-based command handlers, but also AOP-style handlers written as
3542
regular methods. Besides that, it unifies command handler API (pipeline behaviors and handlers
3643
are the same there) and helps to eliminate nearly all boilerplate code you'd have otherwise.
3744
* [Stl.Fusion](https://www.nuget.org/packages/Stl.Fusion/) - depends on `Stl`, `Stl.Interception`, and `Stl.CommandR`.
3845
Nearly everything related to Fusion is there.
39-
* [Stl.Fusion.Server](https://www.nuget.org/packages/Stl.Fusion.Server/) - depends on `Stl.Fusion` and `Stl.Net`.
40-
It implements server-side WebSocket endpoint allowing client-side counterpart to communicate
41-
with Fusion `Publisher`. In addition, it provides a base class for fusion API controllers
42-
(`FusionController`) and a few extension methods helping to register all of that in your web app.
46+
* [Stl.Fusion.Ext.Contracts](https://www.nuget.org/packages/Stl.Fusion.Ext.Contracts/) - depends on `Stl.Fusion`.
47+
Contracts for some handy extensions (ready-to-use Fusion services) - e.g. Fusion-based authentication is there.
48+
* [Stl.Fusion.Ext.Services](https://www.nuget.org/packages/Stl.Fusion.Ext.Services/) - depends on `Stl.Fusion.Ext.Contracts` and `Stl.Fusion.EntityFramework`.
49+
Implementations of extension contracts from `Stl.Fusion.Ext.Contracts`.
50+
* [Stl.Fusion.Server](https://www.nuget.org/packages/Stl.Fusion.Server/) - depends on `Stl.Fusion` and `Stl.Rpc`.
51+
Basically, Fusion + `Stl.Rpc.Server` + some handy server-side helpers.
4352
* [Stl.Fusion.Server.NetFx](https://www.nuget.org/packages/Stl.Fusion.Server.NetFx/) -
4453
.NET Framework 4.X version of `Stl.Fusion.Server`.
45-
* [Stl.Fusion.Client](https://www.nuget.org/packages/Stl.Fusion.Client/) - depends on `Stl.Fusion` and `Stl.Net`.
46-
Implements a client-side WebSocket communication channel and
47-
[RestEase](https://github.com/canton7/RestEase) - based API client builder compatible with
48-
`FusionControler`-based API endpoints. All of that together allows you to get computed
49-
instances on the client that "mirror" their server-side counterparts.
50-
* [Stl.Fusion.Blazor](https://www.nuget.org/packages/Stl.Fusion.Blazor/) - depends on `Stl.Fusion.Client`.
51-
Implements handy Blazor components. Currently there is `StatefulCompontentBase<TState>`
52-
and its 2 descendants: `ComputedStateComponent<T>` and `ComputedStateComponent<T, TLocals>`.
54+
* [Stl.Fusion.Blazor](https://www.nuget.org/packages/Stl.Fusion.Blazor/) - depends on `Stl.Fusion`.
55+
Provides Blazor-Fusion integration. Most importantly, there is `StatefulCompontentBase<TState>`,
56+
which allows to create auto-updating components which recompute their state once the data they consume
57+
from Fusion services changes.
58+
* [Stl.Fusion.Blazor.Authentication](https://www.nuget.org/packages/Stl.Fusion.Blazor.Authentication/) - depends on `Stl.Fusion.Blazor` and `Stl.Fusion.Ext.Contracts`.
59+
Implements Fusion authentication-related Blazor components.
5360
* [Stl.Fusion.EntityFramework](https://www.nuget.org/packages/Stl.Fusion.EntityFramework/) - depends on `Stl.Fusion`.
54-
Contains [EF Core](https://docs.microsoft.com/en-us/ef/) - based implementation of
55-
Fusion authentication, operation persistence, `IKeyValueStore`, etc.
61+
Contains [EF Core](https://docs.microsoft.com/en-us/ef/) integrations for CommandR and Fusion.
5662
* [Stl.Fusion.EntityFramework.Npgsql](https://www.nuget.org/packages/Stl.Fusion.EntityFramework.Npgsql/) -
5763
depends on `Stl.Fusion.EntityFramework`.
5864
Contains [Npgsql](https://www.npgsql.org/) - based implementation of operation log change tracking.
5965
PostgreSQL has [`NOTIFY / LISTEN`](https://www.postgresql.org/docs/13/sql-notify.html)
6066
commands allowing to use it as a message queue, so if you use this database,
6167
you don't need a separate message queue to allow Fusion to notify peer hosts about
6268
operation log changes.
69+
* [Stl.Fusion.EntityFramework.Redis](https://www.nuget.org/packages/Stl.Fusion.EntityFramework.Redis/) -
70+
depends on `Stl.Fusion.EntityFramework`.
71+
Contains [Redis](https://redis.com/) - based implementation of operation log change tracking.
6372

64-
#### [Next: Part 1 &raquo;](./Part01.md) | [Tutorial Home](./README.md)
73+
There are some other packages, but more likely than not you won't need them.
74+
The complete list can be found here (the packages with the most recent version aren't obsolete):
75+
- https://www.nuget.org/packages?q=Tags%3A%22stl_fusion%22
6576

77+
78+
#### [Next: Part 1 &raquo;](./Part01.md) | [Tutorial Home](./README.md)

docs/tutorial/Part01.cs

+6-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Concurrent;
33
using System.Threading.Tasks;
44
using Microsoft.Extensions.DependencyInjection;
5-
using Stl.Async;
65
using Stl.Fusion;
76
using static System.Console;
87

@@ -15,15 +14,15 @@ public static IServiceProvider CreateServices()
1514
{
1615
var services = new ServiceCollection();
1716
var fusion = services.AddFusion();
18-
fusion.AddComputeService<CounterService>();
19-
fusion.AddComputeService<CounterSumService>(); // We'll be using it later
20-
fusion.AddComputeService<HelloService>(); // We'll be using it later
17+
fusion.AddService<CounterService>();
18+
fusion.AddService<CounterSumService>(); // We'll be using it later
19+
fusion.AddService<HelloService>(); // We'll be using it later
2120
return services.BuildServiceProvider();
2221
}
2322
#endregion
2423

2524
#region Part01_CounterService
26-
public class CounterService
25+
public class CounterService : IComputeService
2726
{
2827
private readonly ConcurrentDictionary<string, int> _counters = new ConcurrentDictionary<string, int>();
2928

@@ -73,7 +72,7 @@ public static async Task UseCounterService3()
7372
}
7473

7574
#region Part01_CounterSumService
76-
public class CounterSumService
75+
public class CounterSumService : IComputeService
7776
{
7877
public CounterService Counters { get; }
7978

@@ -125,7 +124,7 @@ public static async Task UseCounterSumService3()
125124
}
126125

127126
#region Part01_HelloService
128-
public class HelloService
127+
public class HelloService : IComputeService
129128
{
130129
[ComputeMethod]
131130
public virtual async Task<string> Hello(string name)

docs/tutorial/Part01.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ public static IServiceProvider CreateServices()
3333
{
3434
var services = new ServiceCollection();
3535
var fusion = services.AddFusion();
36-
fusion.AddComputeService<CounterService>();
37-
fusion.AddComputeService<CounterSumService>(); // We'll be using it later
38-
fusion.AddComputeService<HelloService>(); // We'll be using it later
36+
fusion.AddService<CounterService>();
37+
fusion.AddService<CounterSumService>(); // We'll be using it later
38+
fusion.AddService<HelloService>(); // We'll be using it later
3939
return services.BuildServiceProvider();
4040
}
4141
```
4242

4343
Now we're ready to declare our first Compute Service:
4444

4545
``` cs --editable false --region Part01_CounterService --source-file Part01.cs
46-
public class CounterService
46+
public class CounterService : IComputeService
4747
{
4848
private readonly ConcurrentDictionary<string, int> _counters = new ConcurrentDictionary<string, int>();
4949

@@ -137,7 +137,7 @@ it was printed just for the first call.
137137
Now let's add another Compute Service:
138138

139139
``` cs --editable false --region Part01_CounterSumService --source-file Part01.cs
140-
public class CounterSumService
140+
public class CounterSumService : IComputeService
141141
{
142142
public CounterService Counters { get; }
143143

@@ -255,7 +255,7 @@ To close this section, let's look at the last property closer.
255255
Let's create a simple service to test how Fusion handles concurrency:
256256

257257
``` cs --editable false --region Part01_HelloService --source-file Part01.cs
258-
public class HelloService
258+
public class HelloService : IComputeService
259259
{
260260
[ComputeMethod]
261261
public virtual async Task<string> Hello(string name)
@@ -321,4 +321,3 @@ Overall, nearly everything in Fusion supports concurrent invocations:
321321
as types that aren't supposed to be concurrent (e.g. all Blazor components - `StatefulComponentBase<TState>` and its descendants).
322322

323323
#### [Next: Part 2 &raquo;](./Part02.md) | [Tutorial Home](./README.md)
324-

docs/tutorial/Part02.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Concurrent;
33
using System.Threading.Tasks;
44
using Microsoft.Extensions.DependencyInjection;
5-
using Stl.Async;
65
using Stl.Fusion;
76
using static System.Console;
87

@@ -11,7 +10,7 @@ namespace Tutorial
1110
public static class Part02
1211
{
1312
#region Part02_CounterService
14-
public class CounterService
13+
public class CounterService : IComputeService
1514
{
1615
private readonly ConcurrentDictionary<string, int> _counters = new ConcurrentDictionary<string, int>();
1716

@@ -35,7 +34,7 @@ public static IServiceProvider CreateServices()
3534
{
3635
var services = new ServiceCollection();
3736
var fusion = services.AddFusion();
38-
fusion.AddComputeService<CounterService>();
37+
fusion.AddService<CounterService>();
3938
return services.BuildServiceProvider();
4039
}
4140
#endregion

docs/tutorial/Part02.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ We're going to use the same `CounterService` and `CreateServices` helper
1414
as in Part 1:
1515

1616
``` cs --editable false --region Part02_CounterService --source-file Part02.cs
17-
public class CounterService
17+
public class CounterService : IComputeService
1818
{
1919
private readonly ConcurrentDictionary<string, int> _counters = new ConcurrentDictionary<string, int>();
2020

@@ -38,7 +38,7 @@ public static IServiceProvider CreateServices()
3838
{
3939
var services = new ServiceCollection();
4040
var fusion = services.AddFusion();
41-
fusion.AddComputeService<CounterService>();
41+
fusion.AddService<CounterService>();
4242
return services.BuildServiceProvider();
4343
}
4444
```
@@ -341,4 +341,3 @@ you normally don't even need to know these abstractions exist.
341341
But they'll be ready to help you once you conclude you need throttling.
342342

343343
#### [Next: Part 3 &raquo;](./Part03.md) | [Tutorial Home](./README.md)
344-

0 commit comments

Comments
 (0)