diff --git a/samples/Clock.Tests/ClockViewModelTest.cs b/samples/Clock.Tests/ClockViewModelTest.cs index 81b2481a4..1f3a8e768 100644 --- a/samples/Clock.Tests/ClockViewModelTest.cs +++ b/samples/Clock.Tests/ClockViewModelTest.cs @@ -60,8 +60,8 @@ public void ShouldRefreshDateTimeWhenTimerTick() viewModel.PropertyChanged += (_, args) => { propertyNames.Add(args.PropertyName); }; // When - observer?.OnNext(Tick.Shared); - observer?.OnNext(Tick.Shared); + observer?.OnNext(default); + observer?.OnNext(default); // Then propertyNames.Count(i => i == nameof(IClockViewModel.Date)).ShouldBe(2); diff --git a/samples/Clock/Models/Tick.cs b/samples/Clock/Models/Tick.cs index 69e8b1b02..7c86e021e 100644 --- a/samples/Clock/Models/Tick.cs +++ b/samples/Clock/Models/Tick.cs @@ -1,6 +1,3 @@ namespace Clock.Models; -public struct Tick -{ - public static readonly Tick Shared = new(); -} \ No newline at end of file +public readonly record struct Tick; \ No newline at end of file diff --git a/samples/Clock/Models/Timer.cs b/samples/Clock/Models/Timer.cs index e26a7eefa..8389e05b4 100644 --- a/samples/Clock/Models/Timer.cs +++ b/samples/Clock/Models/Timer.cs @@ -25,16 +25,7 @@ public IDisposable Subscribe(IObserver observer) } _log.Info("Subscribed"); - - return new Token(() => - { - lock (observer) - { - _observers.Remove(observer); - } - - _log.Info("Unsubscribed"); - }); + return new Token(this, observer); } public void Dispose() @@ -53,14 +44,20 @@ private void Tick(object? state) foreach (var observer in observers) { - observer.OnNext(Models.Tick.Shared); + observer.OnNext(default); } } - private class Token(Action action) : IDisposable + private class Token(Timer timer, IObserver observer) : IDisposable { - private readonly Action _action = action ?? throw new ArgumentNullException(nameof(action)); - - public void Dispose() => _action(); + public void Dispose() + { + lock (observer) + { + timer._observers.Remove(observer); + } + + timer._log.Info("Unsubscribed"); + } } } \ No newline at end of file diff --git a/samples/Clock/ViewModels/ClockViewModel.cs b/samples/Clock/ViewModels/ClockViewModel.cs index 91f90099b..d9aa2f676 100644 --- a/samples/Clock/ViewModels/ClockViewModel.cs +++ b/samples/Clock/ViewModels/ClockViewModel.cs @@ -8,6 +8,7 @@ internal class ClockViewModel : ViewModel, IClockViewModel, IDisposable, IObserv private readonly ILog _log; private readonly IClock _clock; private readonly IDisposable _timerToken; + private DateTimeOffset _now; public ClockViewModel( ILog log, @@ -16,16 +17,18 @@ public ClockViewModel( { _log = log; _clock = clock; + _now = _clock.Now; _timerToken = timer.Subscribe(this); log.Info("Created"); } - public string Time => _clock.Now.ToString("T"); + public string Time => _now.ToString("T"); - public string Date => _clock.Now.ToString("d"); + public string Date => _now.ToString("d"); void IObserver.OnNext(Tick value) { + _now = _clock.Now; _log.Info("Tick"); OnPropertyChanged(nameof(Time)); OnPropertyChanged(nameof(Date)); diff --git a/src/Pure.DI.Core/Core/Code/ClassCommenter.cs b/src/Pure.DI.Core/Core/Code/ClassCommenter.cs index 4623700c0..659c118f6 100644 --- a/src/Pure.DI.Core/Core/Code/ClassCommenter.cs +++ b/src/Pure.DI.Core/Core/Code/ClassCommenter.cs @@ -1,4 +1,5 @@ -namespace Pure.DI.Core.Code; +// ReSharper disable ConvertIfStatementToConditionalTernaryExpression +namespace Pure.DI.Core.Code; internal class ClassCommenter( IFormatter formatter, @@ -15,7 +16,6 @@ public void AddComments(CompositionCode composition, Unit unit) return; } - var privateRootAdditionalComment = $"is a private composition root that can be resolved by methods like ."; var classComments = composition.Source.Source.Comments; var code = composition.Code; if (classComments.Count <= 0 && composition.Roots.Length <= 0) @@ -56,19 +56,49 @@ public void AddComments(CompositionCode composition, Unit unit) IReadOnlyCollection CreateRootTerms(Root root) { var term = new StringBuilder(); - term.Append(formatter.FormatRef(root.Injection.Type)); - term.Append(' '); - term.Append(root.IsPublic ? formatter.FormatRef(root) : privateRootAdditionalComment); - + if (root.IsPublic) + { + term.Append(formatter.FormatRef(root.Injection.Type)); + term.Append(' '); + term.Append(formatter.FormatRef(root)); + } + else + { + term.Append("Private composition root of type "); + term.Append(formatter.FormatRef(root.Injection.Type)); + term.Append('.'); + } + var resolvers = resolversBuilder.Build(ImmutableArray.Create(root)); if (!resolvers.Any()) { return [term.ToString()]; } + + if (root.IsPublic) + { + term.Append("
or using "); + } + else + { + term.Append(" It can be resolved by "); + } + + if (root.Injection.Tag is null) + { + term.Append(formatter.FormatRef($"{hints.ResolveMethodName}{{T}}()")); + term.Append(" method: "); + term.Append(hints.ResolveMethodName); + term.Append("<"); + } + else + { + term.Append(formatter.FormatRef($"{hints.ResolveByTagMethodName}{{T}}(object)")); + term.Append(" method: "); + term.Append(hints.ResolveByTagMethodName); + term.Append("<"); + } - term.Append("
or using "); - term.Append(formatter.FormatRef($"Resolve{{T}}({(root.Injection.Tag != null ? "object" : "")})")); - term.Append(" method: Resolve<"); term.Append(comments.Escape(root.TypeDescription.Name)); term.Append(">("); term.Append(root.Injection.Tag != null ? root.Injection.Tag.ValueToString() : ""); diff --git a/tests/Pure.DI.UsageTests/Basics/ResolveScenario.cs b/tests/Pure.DI.UsageTests/Basics/ResolveScenario.cs index 45722354e..a6300dccb 100644 --- a/tests/Pure.DI.UsageTests/Basics/ResolveScenario.cs +++ b/tests/Pure.DI.UsageTests/Basics/ResolveScenario.cs @@ -36,9 +36,9 @@ public void Run() // { DI.Setup(nameof(Composition)) .Bind().To() - // Specifies to create a regular public composition root - // of type "IDependency" with the name "DependencySingleton" - .Root("DependencySingleton") + // Specifies to create a private composition root + // of type "IDependency" with the name "Dependency" + .Root() .Bind().To() // Specifies to create a private root // that is only accessible from _Resolve_ methods