Skip to content

Commit

Permalink
Minor
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Mar 13, 2024
1 parent d1ed13f commit 8fc81c5
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 35 deletions.
4 changes: 2 additions & 2 deletions samples/Clock.Tests/ClockViewModelTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 1 addition & 4 deletions samples/Clock/Models/Tick.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
namespace Clock.Models;

public struct Tick
{
public static readonly Tick Shared = new();
}
public readonly record struct Tick;
27 changes: 12 additions & 15 deletions samples/Clock/Models/Timer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,7 @@ public IDisposable Subscribe(IObserver<Tick> observer)
}

_log.Info("Subscribed");

return new Token(() =>
{
lock (observer)
{
_observers.Remove(observer);
}

_log.Info("Unsubscribed");
});
return new Token(this, observer);
}

public void Dispose()
Expand All @@ -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<Tick> 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");
}
}
}
7 changes: 5 additions & 2 deletions samples/Clock/ViewModels/ClockViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ internal class ClockViewModel : ViewModel, IClockViewModel, IDisposable, IObserv
private readonly ILog<ClockViewModel> _log;
private readonly IClock _clock;
private readonly IDisposable _timerToken;
private DateTimeOffset _now;

public ClockViewModel(
ILog<ClockViewModel> log,
Expand All @@ -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<Tick>.OnNext(Tick value)
{
_now = _clock.Now;
_log.Info("Tick");
OnPropertyChanged(nameof(Time));
OnPropertyChanged(nameof(Date));
Expand Down
48 changes: 39 additions & 9 deletions src/Pure.DI.Core/Core/Code/ClassCommenter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
namespace Pure.DI.Core.Code;
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
namespace Pure.DI.Core.Code;

internal class ClassCommenter(
IFormatter formatter,
Expand All @@ -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 <see cref=\"{hints.ResolveMethodName}{{T}}()\"/>.";
var classComments = composition.Source.Source.Comments;
var code = composition.Code;
if (classComments.Count <= 0 && composition.Roots.Length <= 0)
Expand Down Expand Up @@ -56,19 +56,49 @@ public void AddComments(CompositionCode composition, Unit unit)
IReadOnlyCollection<string> 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("<br/>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: <c>");
term.Append(hints.ResolveMethodName);
term.Append("&lt;");
}
else
{
term.Append(formatter.FormatRef($"{hints.ResolveByTagMethodName}{{T}}(object)"));
term.Append(" method: <c>");
term.Append(hints.ResolveByTagMethodName);
term.Append("&lt;");
}

term.Append("<br/>or using ");
term.Append(formatter.FormatRef($"Resolve{{T}}({(root.Injection.Tag != null ? "object" : "")})"));
term.Append(" method: <c>Resolve&lt;");
term.Append(comments.Escape(root.TypeDescription.Name));
term.Append("&gt;(");
term.Append(root.Injection.Tag != null ? root.Injection.Tag.ValueToString() : "");
Expand Down
6 changes: 3 additions & 3 deletions tests/Pure.DI.UsageTests/Basics/ResolveScenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ public void Run()
// {
DI.Setup(nameof(Composition))
.Bind<IDependency>().To<Dependency>()
// Specifies to create a regular public composition root
// of type "IDependency" with the name "DependencySingleton"
.Root<IDependency>("DependencySingleton")
// Specifies to create a private composition root
// of type "IDependency" with the name "Dependency"
.Root<IDependency>()
.Bind<IService>().To<Service>()
// Specifies to create a private root
// that is only accessible from _Resolve_ methods
Expand Down

0 comments on commit 8fc81c5

Please sign in to comment.