Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Jan 24, 2025
1 parent cdfd107 commit c8d1313
Show file tree
Hide file tree
Showing 23 changed files with 334 additions and 62 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ dotnet run
- [Generic builders](readme/generic-builders.md)
### Attributes
- [Constructor ordinal attribute](readme/constructor-ordinal-attribute.md)
- [Dependency attribute](readme/dependency-attribute.md)
- [Member ordinal attribute](readme/member-ordinal-attribute.md)
- [Tag attribute](readme/tag-attribute.md)
- [Type attribute](readme/type-attribute.md)
Expand Down
10 changes: 5 additions & 5 deletions readme/build-up-of-an-existing-generic-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ interface IDependency<out T>
class Dependency<T> : IDependency<T>
where T: struct
{
// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(1)]
// The Dependency attribute specifies to perform an injection
[Dependency]
public string Name { get; set; } = "";

public T Id { get; private set; }

// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(0)]
// The Dependency attribute specifies to perform an injection
[Dependency]
public void SetId(T id) => Id = id;
}

Expand Down Expand Up @@ -111,8 +111,8 @@ partial class Composition
Guid transientGuid2 = Guid.NewGuid();
Dependency<Guid> transientDependency1;
Dependency<Guid> localDependency56 = new Dependency<Guid>();
localDependency56.SetId(transientGuid2);
localDependency56.Name = name;
localDependency56.SetId(transientGuid2);
transientDependency1 = localDependency56;
return new Service<Guid>(transientDependency1);
}
Expand Down
10 changes: 5 additions & 5 deletions readme/build-up-of-an-existing-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ interface IDependency

class Dependency : IDependency
{
// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(1)]
// The Dependency attribute specifies to perform an injection and its order
[Dependency]
public string Name { get; set; } = "";

public Guid Id { get; private set; } = Guid.Empty;

// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(0)]
// The Dependency attribute specifies to perform an injection and its order
[Dependency]
public void SetId(Guid id) => Id = id;
}

Expand Down Expand Up @@ -107,8 +107,8 @@ partial class Composition
Guid transientGuid2 = Guid.NewGuid();
Dependency transientDependency1;
var localDependency50 = new Dependency();
localDependency50.SetId(transientGuid2);
localDependency50.Name = name;
localDependency50.SetId(transientGuid2);
transientDependency1 = localDependency50;
return new Service(transientDependency1);
}
Expand Down
18 changes: 9 additions & 9 deletions readme/builders.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,26 @@ record Service1: IService
{
public Guid Id { get; private set; } = Guid.Empty;

[Ordinal(1)]
// The Dependency attribute specifies to perform an injection
[Dependency]
public IDependency? Dependency { get; set; }

// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(2)]
// The Dependency attribute specifies to perform an injection
[Dependency]
public void SetId(Guid id) => Id = id;
}

record Service2: IService
{
public Guid Id { get; private set; } = Guid.Empty;

[Ordinal(1)]
[Dependency]
public IDependency? Dependency => DependencyFactory?.Invoke();

[Ordinal(2)]
[Dependency]
public Func<IDependency>? DependencyFactory { get; set; }

// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(3)]
[Dependency]
public void SetId(Guid id) => Id = id;
}
```
Expand Down Expand Up @@ -200,10 +200,10 @@ classDiagram
Dependency --|> IDependency
Composition ..> Service2 : Service2 BuildUp(Pure.DI.UsageTests.Basics.BuilderScenario.Service2 instance)
Composition ..> Service1 : Service1 BuildUp(Pure.DI.UsageTests.Basics.BuilderScenario.Service1 instance)
Service2 o-- Service2 : "2M01D24di" Argument "instance"
Service2 o-- Service2 : "0M01D24di" Argument "instance"
Service2 o-- "PerBlock" FuncᐸIDependencyᐳ : FuncᐸIDependencyᐳ
Service2 *-- Guid : Guid
Service1 o-- Service1 : "0M01D24di" Argument "instance"
Service1 o-- Service1 : "2M01D24di" Argument "instance"
Service1 *-- Dependency : IDependency
Service1 *-- Guid : Guid
FuncᐸIDependencyᐳ *-- Dependency : IDependency
Expand Down
4 changes: 2 additions & 2 deletions readme/complex-generic-root-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ interface IService<out T>

class Service<T> : IService<T>
{
// The Ordinal attribute specifies to perform an injection,
// The Dependency attribute specifies to perform an injection,
// the integer value in the argument specifies
// the ordinal of injection
[Ordinal(0)]
[Dependency]
public void SetDependency(MyData<T> data) =>
Val = data.Value;

Expand Down
181 changes: 181 additions & 0 deletions readme/dependency-attribute.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#### Dependency attribute

[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](../tests/Pure.DI.UsageTests/Attributes/DependencyAttributeScenario.cs)

When applied to a property or field, these type members will also participate in dependency injection in the appropriate order from smallest value to largest.


```c#
using Shouldly;
using Pure.DI;
using System.Text;

DI.Setup(nameof(PersonComposition))
.Arg<int>("personId")
.Arg<string>("personName")
.Arg<DateTime>("personBirthday")
.Bind().To<Person>()

// Composition root
.Root<IPerson>("Person");

var composition = new PersonComposition(
personId: 123,
personName: "Nik",
personBirthday: new DateTime(1977, 11, 16));

var person = composition.Person;
person.Name.ShouldBe("123 Nik 1977-11-16");

interface IPerson
{
string Name { get; }
}

class Person : IPerson
{
private readonly StringBuilder _name = new();

public string Name => _name.ToString();

[Dependency] public int Id;

// The Ordinal attribute specifies to perform an injection,
// the integer value in the argument specifies
// the ordinal of injection
[Dependency(ordinal: 1)]
public string FirstName
{
set
{
_name.Append(Id);
_name.Append(' ');
_name.Append(value);
}
}

[Dependency(ordinal: 2)]
public DateTime Birthday
{
set
{
_name.Append(' ');
_name.Append($"{value:yyyy-MM-dd}");
}
}
}
```

<details>
<summary>Running this code sample locally</summary>

- Make sure you have the [.NET SDK 9.0](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) or later is installed
```bash
dotnet --list-sdk
```
- Create a net9.0 (or later) console application
```bash
dotnet new console -n Sample
```
- Add references to NuGet packages
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
- [Shouldly](https://www.nuget.org/packages/Shouldly)
```bash
dotnet add package Pure.DI
dotnet add package Shouldly
```
- Copy the example code into the _Program.cs_ file

You are ready to run the example 🚀
```bash
dotnet run
```

</details>

The attribute `Dependency` is part of the API, but you can use your own attribute at any time, and this allows you to define them in the assembly and namespace you want.

The following partial class will be generated:

```c#
partial class PersonComposition
{
private readonly PersonComposition _root;

private readonly int _argPersonId;
private readonly string _argPersonName;
private readonly DateTime _argPersonBirthday;

[OrdinalAttribute(128)]
public PersonComposition(int personId, string personName, DateTime personBirthday)
{
_argPersonId = personId;
_argPersonName = personName ?? throw new ArgumentNullException(nameof(personName));
_argPersonBirthday = personBirthday;
_root = this;
}

internal PersonComposition(PersonComposition parentScope)
{
_root = (parentScope ?? throw new ArgumentNullException(nameof(parentScope)))._root;
_argPersonId = _root._argPersonId;
_argPersonName = _root._argPersonName;
_argPersonBirthday = _root._argPersonBirthday;
}

public IPerson Person
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
Person transientPerson0 = new Person();
transientPerson0.Id = _argPersonId;
transientPerson0.FirstName = _argPersonName;
transientPerson0.Birthday = _argPersonBirthday;
return transientPerson0;
}
}
}
```

Class diagram:

```mermaid
---
config:
class:
hideEmptyMembersBox: true
---
classDiagram
Person --|> IPerson
PersonComposition ..> Person : IPerson Person
Person o-- Int32 : Argument "personId"
Person o-- String : Argument "personName"
Person o-- DateTime : Argument "personBirthday"
namespace Pure.DI.UsageTests.Attributes.DependencyAttributeScenario {
class IPerson {
<<interface>>
}
class Person {
+Person()
+Int32 Id
+String FirstName
+DateTime Birthday
}
class PersonComposition {
<<partial>>
+IPerson Person
}
}
namespace System {
class DateTime {
<<struct>>
}
class Int32 {
<<struct>>
}
class String {
}
}
```

4 changes: 2 additions & 2 deletions readme/field-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ interface IService

class Service : IService
{
// The Ordinal attribute specifies to perform an injection,
// The Dependency attribute specifies to perform an injection,
// the integer value in the argument specifies
// the ordinal of injection
[Ordinal(0)] internal IDependency? DependencyVal;
[Dependency] internal IDependency? DependencyVal;

public IDependency? Dependency => DependencyVal;
}
Expand Down
5 changes: 2 additions & 3 deletions readme/generic-builders.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ record Service<T, T2>: IService<T, T2>
{
public T Id { get; private set; } = default(T);

[Ordinal(1)]
[Dependency]
public IDependency<T2>? Dependency { get; set; }

// The Ordinal attribute specifies to perform an injection and its order
[Ordinal(2)]
[Dependency]
public void SetId([Tag(Tag.Id)] T id) => Id = id;
}
```
Expand Down
4 changes: 2 additions & 2 deletions readme/generic-root-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ interface IService<out T>

class Service<T> : IService<T>
{
// The Ordinal attribute specifies to perform an injection,
// The Dependency attribute specifies to perform an injection,
// the integer value in the argument specifies
// the ordinal of injection
[Ordinal(0)]
[Dependency]
public void SetDependency(T dependency) =>
Dependency = dependency;

Expand Down
4 changes: 2 additions & 2 deletions readme/method-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ interface IService

class Service : IService
{
// The Ordinal attribute specifies to perform an injection,
// The Dependency attribute specifies to perform an injection,
// the integer value in the argument specifies
// the ordinal of injection
[Ordinal(0)]
[Dependency]
public void SetDependency(IDependency dependency) =>
Dependency = dependency;

Expand Down
4 changes: 2 additions & 2 deletions readme/property-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ interface IService

class Service : IService
{
// The Ordinal attribute specifies to perform an injection,
// The Dependency attribute specifies to perform an injection,
// the integer value in the argument specifies
// the ordinal of injection
[Ordinal(0)]
[Dependency]
public IDependency? Dependency { get; set; }
}
```
Expand Down
2 changes: 1 addition & 1 deletion readme/tag-on-a-method-argument.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ interface IService

class Service : IService
{
[Ordinal(1)]
[Dependency]
public void Initialize(IDependency dep) =>
Dependency = dep;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ interface IService

class Service : IService
{
[Ordinal(1)]
[Dependency]
public void Initialize(IDependency dep) =>
Dependency = dep;

Expand Down
Loading

0 comments on commit c8d1313

Please sign in to comment.