Introduce preferred constructors (#9)

This commit is contained in:
2022-05-04 14:30:14 +02:00
committed by GitHub
parent df5e389934
commit 84728090d5
8 changed files with 84 additions and 7 deletions
+1 -1
View File
@@ -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
+2
View File
@@ -87,3 +87,5 @@ To retrieve all services of a certain type from the service manager, use
serviceManager.GetServicesOfType<ISharedInterface>();
```
This will return an `IEnumerable<ISharedInterface>` 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.
@@ -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;
}
}
}
+23
View File
@@ -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<IIndependentService, IndependentService>();
di.RegisterSingleton<ServiceWithPrefferedConstructor>();
var service = di.GetService<ServiceWithPrefferedConstructor>();
service.CalledPrefferedConstructor.Should().BeTrue();
}
[TestMethod]
public void ServiceWithPrefferedConstructorFallsBackToOtherConstructors()
{
var di = new ServiceManager();
di.RegisterSingleton<ServiceWithPrefferedConstructor>();
var service = di.GetService<ServiceWithPrefferedConstructor>();
service.CalledPrefferedConstructor.Should().BeFalse();
}
}
}
@@ -0,0 +1,18 @@
using System;
namespace Slim.Attributes
{
/// <summary>
/// Attribute used to mark constructors to be used with priority by the <see cref="ServiceManager"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Constructor)]
public sealed class PrefferedConstructorAttribute : Attribute
{
/// <summary>
/// Creates a new instance of <see cref="PrefferedConstructorAttribute"/>.
/// </summary>
public PrefferedConstructorAttribute()
{
}
}
}
+7 -2
View File
@@ -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<PrefferedConstructorAttribute>() is null);
foreach (var constructor in constructors)
{
/*
+3 -3
View File
@@ -8,10 +8,10 @@
<Company />
<Product></Product>
<Description>Service lifetime management and dependency injection framework.</Description>
<AssemblyVersion>1.7</AssemblyVersion>
<FileVersion>1.7</FileVersion>
<AssemblyVersion>1.7.1</AssemblyVersion>
<FileVersion>1.7.1</FileVersion>
<PackageProjectUrl>https://github.com/AlexMacocian/Slim</PackageProjectUrl>
<Version>1.7</Version>
<Version>1.7.1</Version>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
+10
View File
@@ -4,6 +4,16 @@
<name>Slim</name>
</assembly>
<members>
<member name="T:Slim.Attributes.PrefferedConstructorAttribute">
<summary>
Attribute used to mark constructors to be used with priority by the <see cref="T:Slim.ServiceManager"/>.
</summary>
</member>
<member name="M:Slim.Attributes.PrefferedConstructorAttribute.#ctor">
<summary>
Creates a new instance of <see cref="T:Slim.Attributes.PrefferedConstructorAttribute"/>.
</summary>
</member>
<member name="T:Slim.Exceptions.DependencyInjectionException">
<summary>
Exception thrown when <see cref="T:Slim.IServiceManager"/> fails to create a service.