-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
18eccab
commit 6e652c5
Showing
36 changed files
with
522 additions
and
142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
#### DI tracing via serilog | ||
|
||
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](../tests/Pure.DI.UsageTests/Advanced/DITracingViaSerilogScenario.cs) | ||
|
||
|
||
```c# | ||
interface IDependency; | ||
|
||
class Dependency : IDependency; | ||
|
||
interface IService | ||
{ | ||
IDependency Dependency { get; } | ||
} | ||
|
||
class Service : IService | ||
{ | ||
public Service(ILogger<Service> log, IDependency dependency) | ||
{ | ||
Dependency = dependency; | ||
log.Information("Created"); | ||
} | ||
|
||
public IDependency Dependency { get; } | ||
} | ||
|
||
interface ILogger<T>: Serilog.ILogger; | ||
|
||
class Logger<T>(Serilog.ILogger logger) : ILogger<T> | ||
{ | ||
private readonly Serilog.ILogger _logger = | ||
logger.ForContext(typeof(T)); | ||
|
||
public void Write(LogEvent logEvent) => | ||
_logger.Write(logEvent); | ||
} | ||
|
||
partial class Composition | ||
{ | ||
private void Setup() => | ||
DI.Setup(nameof(Composition)) | ||
|
||
.Hint(Hint.OnNewInstance, "On") | ||
.Hint(Hint.OnDependencyInjection, "On") | ||
.Arg<Serilog.ILogger>("logger") | ||
.Bind().As(Lifetime.Singleton).To<Logger<TT>>() | ||
|
||
.Bind().To<Dependency>() | ||
.Bind().To<Service>() | ||
.Root<Serilog.ILogger>(nameof(Log), kind: RootKinds.Private) | ||
.Root<IService>(nameof(Root)); | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
partial void OnNewInstance<T>(ref T value, object? tag, Lifetime lifetime) => | ||
Log.Information("Created [{Value}], tag [{Tag}] as {Lifetime}", value, tag, lifetime); | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private partial T OnDependencyInjection<T>(in T value, object? tag, Lifetime lifetime) | ||
{ | ||
if (typeof(T) != typeof(Serilog.ILogger)) | ||
{ | ||
Log.Information("Injected [{Value}], tag [{Tag}] as {Lifetime}", value, tag, lifetime); | ||
} | ||
|
||
return value; | ||
} | ||
} | ||
|
||
Serilog.ILogger serilogLogger = CreateLogger(); | ||
var composition = new Composition(logger: serilogLogger); | ||
var service = composition.Root; | ||
``` | ||
|
||
The following partial class will be generated: | ||
|
||
```c# | ||
partial class Composition | ||
{ | ||
private readonly Composition _root; | ||
private readonly Lock _lock; | ||
|
||
private Logger<Service>? _singletonLogger47; | ||
|
||
private readonly Serilog.ILogger _argLogger; | ||
|
||
[OrdinalAttribute(128)] | ||
public Composition(Serilog.ILogger logger) | ||
{ | ||
_argLogger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||
_root = this; | ||
_lock = new Lock(); | ||
} | ||
|
||
internal Composition(Composition parentScope) | ||
{ | ||
_root = (parentScope ?? throw new ArgumentNullException(nameof(parentScope)))._root; | ||
_argLogger = _root._argLogger; | ||
_lock = _root._lock; | ||
} | ||
|
||
private Serilog.ILogger Log | ||
{ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
get | ||
{ | ||
return OnDependencyInjection<Serilog.ILogger>(_argLogger, null, Lifetime.Transient); | ||
} | ||
} | ||
|
||
public IService Root | ||
{ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
get | ||
{ | ||
Dependency transientDependency1 = new Dependency(); | ||
OnNewInstance<Dependency>(ref transientDependency1, null, Lifetime.Transient); | ||
if (_root._singletonLogger47 is null) | ||
{ | ||
using (_lock.EnterScope()) | ||
{ | ||
if (_root._singletonLogger47 is null) | ||
{ | ||
Logger<Service> _singletonLogger47Temp; | ||
_singletonLogger47Temp = new Logger<Service>(OnDependencyInjection<Serilog.ILogger>(_argLogger, null, Lifetime.Transient)); | ||
OnNewInstance<Logger<Service>>(ref _singletonLogger47Temp, null, Lifetime.Singleton); | ||
Thread.MemoryBarrier(); | ||
_root._singletonLogger47 = _singletonLogger47Temp; | ||
} | ||
} | ||
} | ||
|
||
Service transientService0 = new Service(OnDependencyInjection<ILogger<Service>>(_root._singletonLogger47!, null, Lifetime.Singleton), OnDependencyInjection<IDependency>(transientDependency1, null, Lifetime.Transient)); | ||
OnNewInstance<Service>(ref transientService0, null, Lifetime.Transient); | ||
return OnDependencyInjection<IService>(transientService0, null, Lifetime.Transient); | ||
} | ||
} | ||
|
||
|
||
partial void OnNewInstance<T>(ref T value, object? tag, Lifetime lifetime); | ||
|
||
private partial T OnDependencyInjection<T>(in T value, object? tag, Lifetime lifetime); | ||
} | ||
``` | ||
|
||
Class diagram: | ||
|
||
```mermaid | ||
--- | ||
config: | ||
class: | ||
hideEmptyMembersBox: true | ||
--- | ||
classDiagram | ||
Service --|> IService | ||
LoggerᐸServiceᐳ --|> ILoggerᐸServiceᐳ | ||
Dependency --|> IDependency | ||
Composition ..> Service : IService Root | ||
Composition ..> ILogger : ILogger Log | ||
Service o-- "Singleton" LoggerᐸServiceᐳ : ILoggerᐸServiceᐳ | ||
Service *-- Dependency : IDependency | ||
LoggerᐸServiceᐳ o-- ILogger : Argument "logger" | ||
namespace Pure.DI.UsageTests.Advanced.DITracingViaSerilogScenario { | ||
class Composition { | ||
<<partial>> | ||
-ILogger Log | ||
+IService Root | ||
} | ||
class Dependency { | ||
+Dependency() | ||
} | ||
class IDependency { | ||
<<interface>> | ||
} | ||
class ILoggerᐸServiceᐳ { | ||
<<interface>> | ||
} | ||
class IService { | ||
<<interface>> | ||
} | ||
class LoggerᐸServiceᐳ { | ||
+Logger(ILogger logger) | ||
} | ||
class Service { | ||
+Service(ILoggerᐸServiceᐳ log, IDependency dependency) | ||
} | ||
} | ||
namespace Serilog { | ||
class ILogger { | ||
<<interface>> | ||
} | ||
} | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.