diff --git a/LICENSE b/LICENSE index 7b4b612..6e3e5eb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Macocian Alexandru Victor +Copyright (c) 2022 Macocian Alexandru Victor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index f468dad..3c457bb 100644 --- a/README.md +++ b/README.md @@ -86,4 +86,6 @@ To retrieve all services of a certain type from the service manager, use ```c# serviceManager.GetServicesOfType(); ``` -This will return an `IEnumerable` with all the services which implement the `ISharedInterface`. \ No newline at end of file +This will return an `IEnumerable` with all the services which implement the `ISharedInterface`. + +In order to give priority to certain constructors in a class, mark the constructors with `[PreferredConstructor]` attribute. `ServiceManager` will prioritize those constructors. \ No newline at end of file diff --git a/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs b/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs new file mode 100644 index 0000000..1a996a9 --- /dev/null +++ b/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs @@ -0,0 +1,19 @@ +using Slim.Attributes; + +namespace Slim.Tests.Models +{ + public sealed class ServiceWithPrefferedConstructor + { + public bool CalledPrefferedConstructor { get; init; } + + public ServiceWithPrefferedConstructor() + { + } + + [PrefferedConstructor] + public ServiceWithPrefferedConstructor(IIndependentService independentService) + { + this.CalledPrefferedConstructor = true; + } + } +} diff --git a/Slim.Tests/ServiceManagerTests.cs b/Slim.Tests/ServiceManagerTests.cs index a933934..230633b 100644 --- a/Slim.Tests/ServiceManagerTests.cs +++ b/Slim.Tests/ServiceManagerTests.cs @@ -727,5 +727,28 @@ namespace Slim.Tests dependentService1.Should().Be(dependentService2); dependentService1.IndependentService.Should().Be(dependentService2.IndependentService); } + + [TestMethod] + public void ServiceWithPrefferedConstructorCallsPrefferedConstructor() + { + var di = new ServiceManager(); + di.RegisterSingleton(); + di.RegisterSingleton(); + + var service = di.GetService(); + + service.CalledPrefferedConstructor.Should().BeTrue(); + } + + [TestMethod] + public void ServiceWithPrefferedConstructorFallsBackToOtherConstructors() + { + var di = new ServiceManager(); + di.RegisterSingleton(); + + var service = di.GetService(); + + service.CalledPrefferedConstructor.Should().BeFalse(); + } } } diff --git a/Slim/Attributes/PrefferedConstructorAttribute.cs b/Slim/Attributes/PrefferedConstructorAttribute.cs new file mode 100644 index 0000000..69ac125 --- /dev/null +++ b/Slim/Attributes/PrefferedConstructorAttribute.cs @@ -0,0 +1,18 @@ +using System; + +namespace Slim.Attributes +{ + /// + /// Attribute used to mark constructors to be used with priority by the . + /// + [AttributeUsage(AttributeTargets.Constructor)] + public sealed class PrefferedConstructorAttribute : Attribute + { + /// + /// Creates a new instance of . + /// + public PrefferedConstructorAttribute() + { + } + } +} diff --git a/Slim/ServiceManager.cs b/Slim/ServiceManager.cs index 4fd5019..dec503c 100644 --- a/Slim/ServiceManager.cs +++ b/Slim/ServiceManager.cs @@ -1,4 +1,5 @@ -using Slim.Exceptions; +using Slim.Attributes; +using Slim.Exceptions; using Slim.Resolvers; using System; using System.Collections.Generic; @@ -682,7 +683,11 @@ namespace Slim } private object FindAndCallConstructors(Type implementType) { - var constructors = implementType.GetConstructors(); + /* + * Order constructors to give priority to constructors that have PrefferedConstructorAttribute decorator + */ + var constructors = implementType.GetConstructors() + .OrderBy(c => c.GetCustomAttribute() is null); foreach (var constructor in constructors) { /* diff --git a/Slim/Slim.csproj b/Slim/Slim.csproj index aed6011..dcd92bc 100644 --- a/Slim/Slim.csproj +++ b/Slim/Slim.csproj @@ -8,10 +8,10 @@ Service lifetime management and dependency injection framework. - 1.7 - 1.7 + 1.7.1 + 1.7.1 https://github.com/AlexMacocian/Slim - 1.7 + 1.7.1 true true LICENSE diff --git a/Slim/Slim.xml b/Slim/Slim.xml index 4cd78e6..3347085 100644 --- a/Slim/Slim.xml +++ b/Slim/Slim.xml @@ -4,6 +4,16 @@ Slim + + + Attribute used to mark constructors to be used with priority by the . + + + + + Creates a new instance of . + + Exception thrown when fails to create a service.