Skip to content

Commit 7e3b7ef

Browse files
authored
Fixed issues with service provider scopes in reactive nodes. (#185)
* Fixing context lifetime for scoped nodes. * Using correct scope in when adding a node source. * Implemented unit tests for reactive node. * Updated unit tests * Fixed warnings in tests. * Fixed unit tests
1 parent d19f01b commit 7e3b7ef

5 files changed

Lines changed: 399 additions & 13 deletions

File tree

src/CodeCasa.AutomationPipelines.Lights/ReactiveNode/CompositeLightTransitionReactiveNodeConfigurator.Cycle.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@ public ILightTransitionReactiveNodeConfigurator AddCycle<T>(IObservable<T> trigg
5252
configure(compositeCycleConfigurator);
5353
configurators.ForEach(kvp => kvp.Value.AddNodeSource(triggerObservable.ToCycleObservable(cycleConfigurators[kvp.Key].CycleNodeFactories.Select(tuple =>
5454
{
55-
var serviceScope = serviceProvider.CreateScope();
56-
var context = new LightPipelineContext(serviceScope.ServiceProvider, kvp.Value.Light);
57-
var factory = new Func<IPipelineNode<LightTransition>>(() => new ScopedNode<LightTransition>(serviceScope, tuple.nodeFactory(context)));
58-
var valueIsActiveFunc = () => tuple.matchesNodeState(context);
55+
var factory = new Func<IPipelineNode<LightTransition>>(() =>
56+
{
57+
var serviceScope = serviceProvider.CreateScope();
58+
var context = new LightPipelineContext(serviceScope.ServiceProvider, kvp.Value.Light);
59+
return new ScopedNode<LightTransition>(serviceScope, tuple.nodeFactory(context));
60+
});
61+
var valueIsActiveFunc = () => tuple.matchesNodeState(new LightPipelineContext(serviceProvider, kvp.Value.Light));
5962
return (factory, valueIsActiveFunc);
6063
}))));
6164
return this;

src/CodeCasa.AutomationPipelines.Lights/ReactiveNode/LightTransitionReactiveNodeConfigurator.Cycle.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,13 @@ public ILightTransitionReactiveNodeConfigurator AddCycle<T>(IObservable<T> trigg
5151
configure(cycleConfigurator);
5252
AddNodeSource(triggerObservable.ToCycleObservable(cycleConfigurator.CycleNodeFactories.Select(tuple =>
5353
{
54-
var serviceScope = serviceProvider.CreateScope();
55-
var context = new LightPipelineContext(serviceScope.ServiceProvider, Light);
56-
var factory = new Func<IPipelineNode<LightTransition>>(() => new ScopedNode<LightTransition>(serviceScope, tuple.nodeFactory(context)));
57-
var valueIsActiveFunc = () => tuple.matchesNodeState(context);
54+
var factory = new Func<IPipelineNode<LightTransition>>(() =>
55+
{
56+
var serviceScope = serviceProvider.CreateScope();
57+
var context = new LightPipelineContext(serviceScope.ServiceProvider, Light);
58+
return new ScopedNode<LightTransition>(serviceScope, tuple.nodeFactory(context));
59+
});
60+
var valueIsActiveFunc = () => tuple.matchesNodeState(new LightPipelineContext(serviceProvider, Light));
5861
return (factory, valueIsActiveFunc);
5962
})));
6063
return this;

src/CodeCasa.AutomationPipelines.Lights/ReactiveNode/LightTransitionReactiveNodeConfigurator.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
using System.Reactive;
2-
using System.Reactive.Concurrency;
3-
using System.Reactive.Linq;
4-
using CodeCasa.Abstractions;
1+
using CodeCasa.Abstractions;
52
using CodeCasa.AutomationPipelines.Lights.Context;
63
using CodeCasa.AutomationPipelines.Lights.Extensions;
74
using CodeCasa.AutomationPipelines.Lights.Nodes;
85
using CodeCasa.AutomationPipelines.Lights.Pipeline;
96
using CodeCasa.Lights;
7+
using System.Reactive;
8+
using System.Reactive.Concurrency;
9+
using System.Reactive.Linq;
10+
using System.Xml.Linq;
11+
using CodeCasa.AutomationPipelines.Lights.Utils;
12+
using Microsoft.Extensions.DependencyInjection;
1013

1114
namespace CodeCasa.AutomationPipelines.Lights.ReactiveNode;
1215

@@ -99,7 +102,18 @@ public ILightTransitionReactiveNodeConfigurator AddNodeSource(IObservable<IPipel
99102
/// <inheritdoc/>
100103
public ILightTransitionReactiveNodeConfigurator AddNodeSource(IObservable<Func<ILightPipelineContext, IPipelineNode<LightTransition>?>> nodeFactorySource)
101104
{
102-
return AddNodeSource(nodeFactorySource.Select(f => f(new LightPipelineContext(serviceProvider, Light))));
105+
return AddNodeSource(nodeFactorySource.Select(nodeFactory =>
106+
{
107+
var scope = serviceProvider.CreateScope();
108+
var context = new LightPipelineContext(scope.ServiceProvider, Light);
109+
var node = nodeFactory(context);
110+
if (node != null)
111+
{
112+
return new ScopedNode<LightTransition>(scope, node);
113+
}
114+
scope.Dispose();
115+
return null;
116+
}));
103117
}
104118

105119
/// <inheritdoc/>

tests/CodeCasa.AutomationPipelines.Lights.Tests/CodeCasa.AutomationPipelines.Lights.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
<ItemGroup>
1111
<PackageReference Include="MSTest" Version="4.0.2" />
12+
<PackageReference Include="Moq" Version="4.20.72" />
1213
</ItemGroup>
1314

1415
<ItemGroup>

0 commit comments

Comments
 (0)