diff --git a/.run/Build and pack libraries.run.xml b/.run/Build and pack libraries.run.xml new file mode 100644 index 000000000..2f43b6bd8 --- /dev/null +++ b/.run/Build and pack libraries.run.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/.run/Compatibility checks.run.xml b/.run/Compatibility checks.run.xml new file mode 100644 index 000000000..ba5264ba2 --- /dev/null +++ b/.run/Compatibility checks.run.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/Pure.DI.sln b/Pure.DI.sln index db32b5226..704605b4f 100644 --- a/Pure.DI.sln +++ b/Pure.DI.sln @@ -100,6 +100,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalWebAPI", "samples\Mi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SingleRootAvaloniaApp", "samples\SingleRootAvaloniaApp\SingleRootAvaloniaApp.csproj", "{7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pure.DI.Abstractions", "src\Pure.DI.Abstractions\Pure.DI.Abstractions.csproj", "{136A2850-FDA0-4CDB-A798-21C4B4A01974}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -206,6 +208,10 @@ Global {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Release|Any CPU.ActiveCfg = Release|Any CPU {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Release|Any CPU.Build.0 = Release|Any CPU + {136A2850-FDA0-4CDB-A798-21C4B4A01974}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {136A2850-FDA0-4CDB-A798-21C4B4A01974}.Debug|Any CPU.Build.0 = Debug|Any CPU + {136A2850-FDA0-4CDB-A798-21C4B4A01974}.Release|Any CPU.ActiveCfg = Release|Any CPU + {136A2850-FDA0-4CDB-A798-21C4B4A01974}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {7C9E056B-CBA9-4548-9CDB-C5CE03C491B0} = {8163CDD7-7018-4301-A984-803C3807A6A6} @@ -232,5 +238,6 @@ Global {9A3E2271-3090-4BCE-BB48-6C0724CFBE44} = {FA80D231-C641-4A49-99C6-0C065D818B07} {60F18CFA-957B-488F-8292-467D92C17267} = {FA80D231-C641-4A49-99C6-0C065D818B07} {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8} = {FA80D231-C641-4A49-99C6-0C065D818B07} + {136A2850-FDA0-4CDB-A798-21C4B4A01974} = {8163CDD7-7018-4301-A984-803C3807A6A6} EndGlobalSection EndGlobal diff --git a/README.md b/README.md index 6999fde47..39489fe42 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,7 @@ dotnet run - [Member ordinal attribute](readme/member-ordinal-attribute.md) - [Tag attribute](readme/tag-attribute.md) - [Type attribute](readme/type-attribute.md) +- [Inject attribute](readme/inject-attribute.md) - [Custom attributes](readme/custom-attributes.md) - [Custom universal attribute](readme/custom-universal-attribute.md) ### Interception @@ -823,11 +824,12 @@ Then documentation for the composition root: ## NuGet packages -| | | | -|-------------------|---------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------| -| Pure.DI | [![NuGet](https://buildstats.info/nuget/Pure.DI)](https://www.nuget.org/packages/Pure.DI) | DI Source code generator | -| Pure.DI.Templates | [![NuGet](https://buildstats.info/nuget/Pure.DI.Templates)](https://www.nuget.org/packages/Pure.DI.Templates) | Template Package you can call from the shell/command line. | -| Pure.DI.MS | [![NuGet](https://buildstats.info/nuget/Pure.DI.MS)](https://www.nuget.org/packages/Pure.DI.MS) | Tools for working with Microsoft DI | +| | | | +|----------------------|---------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------| +| Pure.DI | [![NuGet](https://buildstats.info/nuget/Pure.DI)](https://www.nuget.org/packages/Pure.DI) | DI Source code generator | +| Pure.DI.Abstractions | [![NuGet](https://buildstats.info/nuget/Pure.DI.Abstractions)](https://www.nuget.org/packages/Pure.DI.Abstractions) | Abstractions for Pure.DI | +| Pure.DI.Templates | [![NuGet](https://buildstats.info/nuget/Pure.DI.Templates)](https://www.nuget.org/packages/Pure.DI.Templates) | Template Package you can call from the shell/command line. | +| Pure.DI.MS | [![NuGet](https://buildstats.info/nuget/Pure.DI.MS)](https://www.nuget.org/packages/Pure.DI.MS) | Tools for working with Microsoft DI | ## Project template diff --git a/build/LibrariesTarget.cs b/build/LibrariesTarget.cs index db0c74cfb..77c2f7843 100644 --- a/build/LibrariesTarget.cs +++ b/build/LibrariesTarget.cs @@ -34,7 +34,16 @@ public Task> RunAsync(CancellationToken cancellatio .Where(i => i.Version.Major >= 7) .Select(v => $"net{v.Version.Major}.{v.Version.Minor}") .ToArray(), - ["webapi"]) + ["webapi"]), + + new Library( + "Pure.DI.Abstractions", + new Package(GetPackagePath("Pure.DI.Abstractions", settings.NextVersion), false), + sdk.Versions + .Where(i => i.Version.Major >= 7) + .Select(v => $"net{v.Version.Major}.{v.Version.Minor}") + .ToArray(), + ["classlib"]) ]; foreach (var library in libraries) diff --git a/readme/FooterTemplate.md b/readme/FooterTemplate.md index 829512588..5d5a2915a 100644 --- a/readme/FooterTemplate.md +++ b/readme/FooterTemplate.md @@ -543,11 +543,12 @@ Then documentation for the composition root: ## NuGet packages -| | | | -|-------------------|---------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------| -| Pure.DI | [![NuGet](https://buildstats.info/nuget/Pure.DI)](https://www.nuget.org/packages/Pure.DI) | DI Source code generator | -| Pure.DI.Templates | [![NuGet](https://buildstats.info/nuget/Pure.DI.Templates)](https://www.nuget.org/packages/Pure.DI.Templates) | Template Package you can call from the shell/command line. | -| Pure.DI.MS | [![NuGet](https://buildstats.info/nuget/Pure.DI.MS)](https://www.nuget.org/packages/Pure.DI.MS) | Tools for working with Microsoft DI | +| | | | +|----------------------|---------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------| +| Pure.DI | [![NuGet](https://buildstats.info/nuget/Pure.DI)](https://www.nuget.org/packages/Pure.DI) | DI Source code generator | +| Pure.DI.Abstractions | [![NuGet](https://buildstats.info/nuget/Pure.DI.Abstractions)](https://www.nuget.org/packages/Pure.DI.Abstractions) | Abstractions for Pure.DI | +| Pure.DI.Templates | [![NuGet](https://buildstats.info/nuget/Pure.DI.Templates)](https://www.nuget.org/packages/Pure.DI.Templates) | Template Package you can call from the shell/command line. | +| Pure.DI.MS | [![NuGet](https://buildstats.info/nuget/Pure.DI.MS)](https://www.nuget.org/packages/Pure.DI.MS) | Tools for working with Microsoft DI | ## Project template diff --git a/readme/inject-attribute.md b/readme/inject-attribute.md new file mode 100644 index 000000000..f77b1a06d --- /dev/null +++ b/readme/inject-attribute.md @@ -0,0 +1,49 @@ +#### Inject attribute + +[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](../tests/Pure.DI.UsageTests/Attributes/InjectAttributeScenario.cs) + +If you want to use attributes in your libraries but don't want to create your own, you can add this package to your projects: + +[![NuGet](https://buildstats.info/nuget/Pure.DI.Abstractions)](https://www.nuget.org/packages/Pure.DI.Abstractions) + +It contains attributes like `Inject` and `Inject` that work for constructors and their arguments, methods and their arguments, properties and fields. They allow you to setup all injection parameters. + + +```c# +using Pure.DI.Abstractions; + +interface IPerson; + +class Person([Inject("NikName")] string name) : IPerson +{ + private object? _state; + + [Inject] + internal object Id = ""; + + public void Initialize([Inject("Person Uri", 1)] object state) => + _state = state; + + public override string ToString() => $"{Id} {name} {_state}"; +} + +DI.Setup(nameof(PersonComposition)) + .Arg("personId") + .Bind("Person Uri").To(_ => new Uri("https://github.com/DevTeam/Pure.DI")) + .Bind("NikName").To(_ => "Nik") + .Bind().To() + + // Composition root + .Root("Person"); + +var composition = new PersonComposition(personId: 123); +var person = composition.Person; +person.ToString().ShouldBe("123 Nik https://github.com/DevTeam/Pure.DI"); +``` + +This package should also be included in a project: + +[![NuGet](https://buildstats.info/nuget/Pure.DI)](https://www.nuget.org/packages/Pure.DI) + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e6bb3344f..b08bcde18 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,11 +2,10 @@ - $(BasePackageId) is not a framework or library, but a source code generator for creating object graphs. To make them accurate, the developer uses a set of intuitive hints from the Pure.DI API. During the compilation phase, Pure.DI determines the optimal graph structure, checks its correctness, and generates partial class code to create object graphs in the Pure DI paradigm using only basic language constructs. The resulting generated code is robust, works everywhere, throws no exceptions, does not depend on .NET library calls or .NET reflections, is efficient in terms of performance and memory consumption, and is subject to all optimizations. This code can be easily integrated into an application because it does not use unnecessary delegates, additional calls to any methods, type conversions, boxing/unboxing, etc. common\icon.png - netstandard2.0 true ..\..\DevTeam.snk + README.md @@ -15,7 +14,6 @@ - diff --git a/src/Library.props b/src/Library.props index a549172b3..89a318e58 100644 --- a/src/Library.props +++ b/src/Library.props @@ -11,11 +11,4 @@ bin - - - true - contentFiles/cs - - - diff --git a/src/Pure.DI.Abstractions/InjectAttribute.cs b/src/Pure.DI.Abstractions/InjectAttribute.cs new file mode 100644 index 000000000..7037cbbfc --- /dev/null +++ b/src/Pure.DI.Abstractions/InjectAttribute.cs @@ -0,0 +1,13 @@ +// ReSharper disable ClassNeverInstantiated.Global +// ReSharper disable RedundantNameQualifier +// ReSharper disable InvalidXmlDocComment +#pragma warning disable CS9113 // Parameter is unread. +namespace Pure.DI.Abstractions; + +/// +/// A universal DI attribute that allows to specify the tag and ordinal of an injection. +/// +/// The injection tag. See also . +/// The injection ordinal. +[global::System.AttributeUsage(global::System.AttributeTargets.Constructor | global::System.AttributeTargets.Method | global::System.AttributeTargets.Parameter | global::System.AttributeTargets.Property | global::System.AttributeTargets.Field)] +public sealed class InjectAttribute(object? tag = default, int ordinal = default) : global::System.Attribute; \ No newline at end of file diff --git a/src/Pure.DI.Abstractions/InjectAttribute`1.cs b/src/Pure.DI.Abstractions/InjectAttribute`1.cs new file mode 100644 index 000000000..fdfe7ad85 --- /dev/null +++ b/src/Pure.DI.Abstractions/InjectAttribute`1.cs @@ -0,0 +1,15 @@ +// ReSharper disable ClassNeverInstantiated.Global +// ReSharper disable UnusedTypeParameter +// ReSharper disable RedundantNameQualifier +// ReSharper disable InvalidXmlDocComment +#pragma warning disable CS9113 // Parameter is unread. +namespace Pure.DI.Abstractions; + +/// +/// A universal DI attribute that allows to specify the type, tag, and ordinal of an injection. +/// +/// The injection tag. See also . +/// The injection ordinal. +/// The injection type. See also and +[global::System.AttributeUsage(global::System.AttributeTargets.Constructor | global::System.AttributeTargets.Method | global::System.AttributeTargets.Parameter | global::System.AttributeTargets.Property | global::System.AttributeTargets.Field)] +public sealed class InjectAttribute(object? tag = default, int ordinal = default) : global::System.Attribute; \ No newline at end of file diff --git a/src/Pure.DI.Abstractions/Pure.DI.Abstractions.csproj b/src/Pure.DI.Abstractions/Pure.DI.Abstractions.csproj new file mode 100644 index 000000000..e1219de09 --- /dev/null +++ b/src/Pure.DI.Abstractions/Pure.DI.Abstractions.csproj @@ -0,0 +1,41 @@ + + + + net20;net35;net40;net45;net48;netstandard1.0;netstandard1.1;netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0;netstandard2.1;netcoreapp1.0;netcoreapp1.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 + true + false + $(BasePackageId).Abstractions + Abstractions of $(BasePackageId). $(Description) + $(DefineConstants);PUREDI_NET_ANY + NU1902;NU1903;NU3005 + + + + + + true + contentFiles/cs/any/Pure.DI/Abstractions + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + + diff --git a/src/Pure.DI.Abstractions/any/Pure.DI/Abstractions/Composition.g.cs b/src/Pure.DI.Abstractions/any/Pure.DI/Abstractions/Composition.g.cs new file mode 100644 index 000000000..751df83f1 --- /dev/null +++ b/src/Pure.DI.Abstractions/any/Pure.DI/Abstractions/Composition.g.cs @@ -0,0 +1,22 @@ +// +// #pragma warning disable +#if !PUREDI_API_SUPPRESSION || PUREDI_API_V1 +#pragma warning disable +namespace Pure.DI.Abstractions +{ + internal static class Composition + { + [global::System.Diagnostics.Conditional("A2768DE22DE3E430C9653990D516CC9B")] + private static void Setup() + { + global::Pure.DI.DI.Setup(kind: global::Pure.DI.CompositionKind.Global) + .TagAttribute>() + .OrdinalAttribute>(1) + .TypeAttribute>() + .TagAttribute() + .OrdinalAttribute(1); + } + } +} +#pragma warning restore +#endif \ No newline at end of file diff --git a/src/Pure.DI.Core/Components/Api.g.cs b/src/Pure.DI.Core/Components/Api.g.cs index 96fbefa61..3ab7ae173 100644 --- a/src/Pure.DI.Core/Components/Api.g.cs +++ b/src/Pure.DI.Core/Components/Api.g.cs @@ -23,9 +23,6 @@ namespace System namespace Pure.DI { - using global::System; - using global::System.Diagnostics; - /// /// Binding lifetimes. /// @@ -1073,7 +1070,7 @@ internal enum CompositionKind ///
See also: ///
///
- [Flags] + [global::System.Flags] internal enum RootKinds { /// @@ -1252,7 +1249,7 @@ public void Dispose() /// The disposable instance. /// Exception occurring during disposal. /// The actual type of instance being disposed of. - partial void OnDisposeException(T disposableInstance, Exception exception) + partial void OnDisposeException(T disposableInstance, global::System.Exception exception) where T : global::System.IDisposable; #if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -1262,7 +1259,7 @@ partial void OnDisposeException(T disposableInstance, Exception exception) /// The disposable instance. /// Exception occurring during disposal. /// The actual type of instance being disposed of. - partial void OnDisposeAsyncException(T asynDisposableInstance, Exception exception) + partial void OnDisposeAsyncException(T asynDisposableInstance, global::System.Exception exception) where T : global::System.IAsyncDisposable; #endif } @@ -1314,7 +1311,7 @@ public T Value get { return _owned.Value; } } - [global::System.Diagnostics.DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] + [global::System.Diagnostics.DebuggerBrowsable(global::System.Diagnostics.DebuggerBrowsableState.Collapsed)] public global::Pure.DI.IOwned Owned { get { return _owned._owned; } diff --git a/src/Pure.DI.Core/Pure.DI.Core.csproj b/src/Pure.DI.Core/Pure.DI.Core.csproj index 308811aaa..2f9b714a1 100644 --- a/src/Pure.DI.Core/Pure.DI.Core.csproj +++ b/src/Pure.DI.Core/Pure.DI.Core.csproj @@ -1,11 +1,13 @@ + netstandard2.0 $(BasePackageId) $(DefineConstants);PUREDI_API_SUPPRESSION;PUREDI_API_V1 + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Pure.DI.MS/Pure.DI.MS.csproj b/src/Pure.DI.MS/Pure.DI.MS.csproj index cd30ea02a..4ae92a4ab 100644 --- a/src/Pure.DI.MS/Pure.DI.MS.csproj +++ b/src/Pure.DI.MS/Pure.DI.MS.csproj @@ -1,6 +1,7 @@ + netstandard2.0 MS Tools for working with Microsoft DI using $(BasePackageId). $(Description) $(DefineConstants);PUREDI_NET_ANY @@ -9,20 +10,16 @@ - - - + + + true + contentFiles/cs + + + true + contentFiles/cs + + - - - true - contentFiles/cs - - - true - contentFiles/cs - - - diff --git a/src/Pure.DI.MS/any/Pure.DI/MS/ServiceProviderFactory.g.cs b/src/Pure.DI.MS/any/Pure.DI/MS/ServiceProviderFactory.g.cs index a0a7196ad..071a7315f 100644 --- a/src/Pure.DI.MS/any/Pure.DI/MS/ServiceProviderFactory.g.cs +++ b/src/Pure.DI.MS/any/Pure.DI/MS/ServiceProviderFactory.g.cs @@ -61,11 +61,11 @@ internal class ServiceProviderFactory: IServiceProviderFactory [global::System.Diagnostics.Conditional("A2768DE22DE3E430C9653990D516CC9B")] private static void HintsSetup() => - DI.Setup(Base, CompositionKind.Internal) - .Hint(Hint.OnCannotResolve, "On") - .Hint(Hint.OnCannotResolvePartial, "Off") - .Hint(Hint.OnNewRoot, "On") - .Hint(Hint.OnNewRootPartial, "Off"); + global::Pure.DI.DI.Setup(Base, global::Pure.DI.CompositionKind.Internal) + .Hint(global::Pure.DI.Hint.OnCannotResolve, "On") + .Hint(global::Pure.DI.Hint.OnCannotResolvePartial, "Off") + .Hint(global::Pure.DI.Hint.OnNewRoot, "On") + .Hint(global::Pure.DI.Hint.OnNewRootPartial, "Off"); /// /// Creates a service collection based on the registered composition. diff --git a/src/Pure.DI.Templates/Pure.DI.Templates.csproj b/src/Pure.DI.Templates/Pure.DI.Templates.csproj index 176db540d..acd758c7b 100644 --- a/src/Pure.DI.Templates/Pure.DI.Templates.csproj +++ b/src/Pure.DI.Templates/Pure.DI.Templates.csproj @@ -1,6 +1,7 @@ + netstandard2.0 Template Pure.DI.Templates Pure DI project templates diff --git a/src/Pure.DI/Pure.DI.csproj b/src/Pure.DI/Pure.DI.csproj index 2ebb3af25..dfa5cd9ed 100644 --- a/src/Pure.DI/Pure.DI.csproj +++ b/src/Pure.DI/Pure.DI.csproj @@ -1,6 +1,8 @@ + netstandard2.0 + $(BasePackageId) is not a framework or library, but a source code generator for creating object graphs. To make them accurate, the developer uses a set of intuitive hints from the Pure.DI API. During the compilation phase, Pure.DI determines the optimal graph structure, checks its correctness, and generates partial class code to create object graphs in the Pure DI paradigm using only basic language constructs. The resulting generated code is robust, works everywhere, throws no exceptions, does not depend on .NET library calls or .NET reflections, is efficient in terms of performance and memory consumption, and is subject to all optimizations. This code can be easily integrated into an application because it does not use unnecessary delegates, additional calls to any methods, type conversions, boxing/unboxing, etc. $(BasePackageId) true false @@ -19,6 +21,7 @@ + diff --git a/tests/Pure.DI.UsageTests/Attributes/InjectAttributeScenario.cs b/tests/Pure.DI.UsageTests/Attributes/InjectAttributeScenario.cs new file mode 100644 index 000000000..211ef9202 --- /dev/null +++ b/tests/Pure.DI.UsageTests/Attributes/InjectAttributeScenario.cs @@ -0,0 +1,71 @@ +/* +$v=true +$p=5 +$d=Inject attribute +$h=If you want to use attributes in your libraries but don't want to create your own, you can add this package to your projects: +$h= +$h=[![NuGet](https://buildstats.info/nuget/Pure.DI.Abstractions)](https://www.nuget.org/packages/Pure.DI.Abstractions) +$h= +$h=It contains attributes like `Inject` and `Inject` that work for constructors and their arguments, methods and their arguments, properties and fields. They allow you to setup all injection parameters. +$f=This package should also be included in a project: +$f= +$f=[![NuGet](https://buildstats.info/nuget/Pure.DI)](https://www.nuget.org/packages/Pure.DI) +*/ + +// ReSharper disable ClassNeverInstantiated.Local +// ReSharper disable CheckNamespace +// ReSharper disable UnusedParameter.Local +// ReSharper disable ClassNeverInstantiated.Global +// ReSharper disable ArrangeTypeModifiers +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedTypeParameter +// ReSharper disable UnusedMember.Global +// ReSharper disable FieldCanBeMadeReadOnly.Global +// ReSharper disable RedundantNameQualifier +#pragma warning disable CS9113 // Parameter is unread. +namespace Pure.DI.UsageTests.Attributes.UniversalAttributeScenario; + +using Xunit; + +// { +using Pure.DI.Abstractions; + +interface IPerson; + +class Person([Inject("NikName")] string name) : IPerson +{ + private object? _state; + + [Inject] + internal object Id = ""; + + public void Initialize([Inject("Person Uri", 1)] object state) => + _state = state; + + public override string ToString() => $"{Id} {name} {_state}"; +} +// } + +public class Scenario +{ + [Fact] + public void Run() + { + // Resolve = Off +// { + DI.Setup(nameof(PersonComposition)) + .Arg("personId") + .Bind("Person Uri").To(_ => new Uri("https://github.com/DevTeam/Pure.DI")) + .Bind("NikName").To(_ => "Nik") + .Bind().To() + + // Composition root + .Root("Person"); + + var composition = new PersonComposition(personId: 123); + var person = composition.Person; + person.ToString().ShouldBe("123 Nik https://github.com/DevTeam/Pure.DI"); +// } + composition.SaveClassDiagram(); + } +} \ No newline at end of file diff --git a/tests/Pure.DI.UsageTests/Pure.DI.UsageTests.csproj b/tests/Pure.DI.UsageTests/Pure.DI.UsageTests.csproj index 6462cb2f3..1e67f9d9a 100644 --- a/tests/Pure.DI.UsageTests/Pure.DI.UsageTests.csproj +++ b/tests/Pure.DI.UsageTests/Pure.DI.UsageTests.csproj @@ -8,21 +8,18 @@ + + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - \ No newline at end of file