Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
run: dotnet run --project Depository.Tests/Depository.Tests.csproj --no-build
1 change: 1 addition & 0 deletions Depository.Abstraction/Depository.Abstraction.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Authors>Kengwang</Authors>
<Description>The Abstraction of Depository</Description>
Expand Down
90 changes: 90 additions & 0 deletions Depository.Abstraction/Extension/Roslyn/AotAttributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Polyfill AOT-related attributes for netstandard2.0 targets.
#if !NET5_0_OR_GREATER
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class,
Inherited = false)]
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
{
public RequiresUnreferencedCodeAttribute(string message) => Message = message;
public string Message { get; }
public string? Url { get; set; }
}

[AttributeUsage(
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct,
Inherited = false)]
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
{
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) =>
MemberTypes = memberTypes;
public DynamicallyAccessedMemberTypes MemberTypes { get; }
}

[Flags]
internal enum DynamicallyAccessedMemberTypes
{
None = 0,
PublicParameterlessConstructor = 0x0001,
PublicConstructors = 0x0002 | PublicParameterlessConstructor,
NonPublicConstructors = 0x0004,
PublicMethods = 0x0008,
NonPublicMethods = 0x0010,
PublicFields = 0x0020,
NonPublicFields = 0x0040,
PublicNestedTypes = 0x0080,
NonPublicNestedTypes = 0x0100,
PublicProperties = 0x0200,
NonPublicProperties = 0x0400,
PublicEvents = 0x0800,
NonPublicEvents = 0x1000,
Interfaces = 0x2000,
All = ~None,
}

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class UnconditionalSuppressMessageAttribute : Attribute
{
public UnconditionalSuppressMessageAttribute(string category, string checkId)
{
Category = category;
CheckId = checkId;
}
public string Category { get; }
public string CheckId { get; }
public string? Scope { get; set; }
public string? Target { get; set; }
public string? MessageId { get; set; }
public string? Justification { get; set; }
}

// RequiresDynamicCodeAttribute was introduced in .NET 7; include it inside the NET5 guard
// since .NET 5 and .NET 6 also lack it and all three need the polyfill together.
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class,
Inherited = false)]
internal sealed class RequiresDynamicCodeAttribute : Attribute
{
public RequiresDynamicCodeAttribute(string message) => Message = message;
public string Message { get; }
public string? Url { get; set; }
}
}
#elif !NET7_0_OR_GREATER
// On .NET 5/6 the other attributes exist in the BCL, but RequiresDynamicCode was only added in .NET 7.
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class,
Inherited = false)]
internal sealed class RequiresDynamicCodeAttribute : Attribute
{
public RequiresDynamicCodeAttribute(string message) => Message = message;
public string Message { get; }
public string? Url { get; set; }
}
}
#endif
14 changes: 11 additions & 3 deletions Depository.Abstraction/Interfaces/IDepositoryResolve.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Depository.Abstraction.Models;
using System.Diagnostics.CodeAnalysis;
using Depository.Abstraction.Models;
using Depository.Abstraction.Models.Options;

namespace Depository.Abstraction.Interfaces;
Expand All @@ -11,15 +12,22 @@ public interface IDepositoryResolve
/// <param name="dependency">Dependency Type</param>
/// <param name="option"></param>
/// <returns></returns>
public List<object> ResolveDependencies(Type dependency, DependencyResolveOption? option = null);
[RequiresDynamicCode("Open-generic type resolution uses MakeGenericType at runtime.")]
public List<object> ResolveDependencies(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type dependency,
DependencyResolveOption? option = null);

/// <summary>
/// Resolve Dependency in Depository
/// </summary>
/// <param name="dependency">Dependency Type</param>
/// <param name="option"></param>
/// <returns></returns>
public object ResolveDependency(Type dependency, DependencyResolveOption? option = null);
[RequiresDynamicCode("Open-generic type resolution uses MakeGenericType at runtime.")]
public object ResolveDependency(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type dependency,
DependencyResolveOption? option = null);

[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void ChangeResolveTarget(Type dependency, object? target);
}
10 changes: 8 additions & 2 deletions Depository.Abstraction/Interfaces/IRelationDepository.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Depository.Abstraction.Models;
using System.Diagnostics.CodeAnalysis;
using Depository.Abstraction.Models;

namespace Depository.Abstraction.Interfaces;

public interface IRelationDepository
{
[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void AddRelation(DependencyDescription dependency, DependencyRelation relation);

public DependencyRelation? GetRelation(DependencyDescription description, bool includeDisabled = false, string? relationName = null);
Expand All @@ -15,6 +17,7 @@ public interface IRelationDepository
/// <param name="description"></param>
/// <param name="relation"></param>
/// <returns></returns>
[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void ChangeFocusingRelation(DependencyDescription description, DependencyRelation relation);

/// <summary>
Expand All @@ -23,12 +26,15 @@ public interface IRelationDepository
/// <param name="description"></param>
/// <param name="relation"></param>
/// <returns></returns>
[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void DeleteRelation(DependencyDescription description, DependencyRelation relation);


public void ClearRelations(DependencyDescription description);

[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void DisableRelation(DependencyDescription description, DependencyRelation relation);


[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void EnableRelation(DependencyDescription description, DependencyRelation relation);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
namespace Depository.Abstraction.Interfaces;
using System.Diagnostics.CodeAnalysis;

namespace Depository.Abstraction.Interfaces;

public interface INotificationHub
{
[RequiresDynamicCode("Open-generic type resolution uses MakeGenericType at runtime.")]
public Task PublishNotificationAsync<TNotification>(TNotification notification, CancellationToken ctk = new());

[RequiresDynamicCode("Open-generic type resolution uses MakeGenericType at runtime.")]
public Task<List<TResult>> PublishNotificationWithResultAsync<TNotification, TResult>(TNotification notification, CancellationToken ctk = new());
}
4 changes: 3 additions & 1 deletion Depository.Abstraction/Models/DependencyRelation.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Depository.Abstraction.Enums;
using System.Diagnostics.CodeAnalysis;
using Depository.Abstraction.Enums;
using Depository.Abstraction.Interfaces;

namespace Depository.Abstraction.Models;

public record DependencyRelation(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
Type ImplementType,
object? DefaultImplementation = null,
string? Name = null,
Expand Down
2 changes: 1 addition & 1 deletion Depository.Core/Depository.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
<Authors>Kengwang</Authors>
<Description>The Core of Depository</Description>
<Copyright>Copyright © Kengwang 2024</Copyright>
<PackageProjectUrl>https://github.com/kengwang/Depository</PackageProjectUrl>
<RepositoryUrl>https://github.com/kengwang/Depository</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand Down
8 changes: 7 additions & 1 deletion Depository.Core/Depository.Relation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Depository.Abstraction.Enums;
using System.Diagnostics.CodeAnalysis;
using Depository.Abstraction.Enums;
using Depository.Abstraction.Exceptions;
using Depository.Abstraction.Models;
using Depository.Abstraction.Models.Options;
Expand All @@ -10,6 +11,7 @@ public partial class Depository
private readonly Dictionary<DependencyDescription, HashSet<DependencyRelation>> _dependencyRelations = new();
private readonly Dictionary<DependencyDescription, DependencyRelation> _currentFocusing = new();

[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void AddRelation(DependencyDescription dependency, DependencyRelation relation)
{
if (Option.CheckerOption.ImplementIsInheritedFromDependency &&
Expand Down Expand Up @@ -47,6 +49,7 @@ public void AddRelation(DependencyDescription dependency, DependencyRelation rel
NotifyDependencyChange(dependency, 1);
}

[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void DeleteRelation(DependencyDescription dependencyType, DependencyRelation relation)
{
if (_dependencyRelations.TryGetValue(dependencyType, out var relations))
Expand All @@ -63,13 +66,15 @@ public void ClearRelations(DependencyDescription dependencyType)
_dependencyRelations.Remove(dependencyType);
}

[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void DisableRelation(DependencyDescription description, DependencyRelation relation)
{
relation.IsEnabled = false;
if (Option.AutoNotifyDependencyChange)
NotifyDependencyChange(description);
}

[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void EnableRelation(DependencyDescription description, DependencyRelation relation)
{
relation.IsEnabled = true;
Expand All @@ -78,6 +83,7 @@ public void EnableRelation(DependencyDescription description, DependencyRelation
}


[RequiresDynamicCode("Dispatching dependency-change notifications uses MakeGenericType at runtime.")]
public void ChangeFocusingRelation(DependencyDescription dependencyDescription,
DependencyRelation relation)
{
Expand Down
Loading