17 Commits

Author SHA1 Message Date
Developer 02
fde0398c89 Bump version to 2.4.2 in project file
Updated the version number, assembly version, and file version from 2.4.1 to 2.4.2 in the DigitalData.Core.Infrastructure.csproj file.
2025-09-30 20:00:36 +02:00
Developer 02
ebf79309d1 Refactor Static class to be generic
Updated the `Static` class in the `DigitalData.Core.Infrastructure` namespace to a generic version `Static<TEntity>`. Removed the original non-generic class and the `GetRepository<TEntity>` method. The new generic class provides a method to retrieve a repository for a specific entity type `TEntity`, enhancing type safety and usability.
2025-09-30 19:58:22 +02:00
Developer 02
5a3cbe8ecf Improve exception message in Static.cs
Updated the exception message in the `Static` class to clarify that services cannot be accessed after the service provider has been created. This change enhances the clarity of the error for developers.
2025-09-30 19:56:58 +02:00
Developer 02
d5a8619b4d Add repository access methods to Static class
This commit introduces two new properties in the `Static` class: `Repository` and `GetRepository<TEntity>()`. The `Repository` property allows retrieval of an `IRepository` instance from the service provider, while `GetRepository<TEntity>()` provides access to a specific `IRepository<TEntity>`. These additions improve the ease of accessing repository instances for data operations.
2025-09-30 19:55:40 +02:00
Developer 02
7689005a14 Add conditional compilation for framework-specific code
Introduce framework-specific handling in `Static.cs` to support both NET and NETFRAMEWORK. Implement lazy initialization for service collection and provider, ensuring proper access and error handling.
2025-09-30 19:48:00 +02:00
Developer 02
05568b1551 Add conditional compilation for .NET Framework support
Updated code to support conditional compilation for .NET Framework and .NET.
Introduced nullable reference types in `DbRepository.cs` and ensured proper initialization of service registration queues in `DependencyInjection.cs`.
Modified `DbRepositoryFactory.cs` and `DbSetFactory.cs` to maintain consistent structure across frameworks.
These changes enhance compatibility and improve type safety.
2025-09-30 18:36:15 +02:00
Developer 02
e0ca11ffc0 Enhance CRUDRepository with conditional compilation
Added preprocessor directive for NET framework support.
Updated using directives to include repository and EF Core
namespaces. Adjusted code structure for improved compatibility.
2025-09-30 18:18:14 +02:00
Developer 02
f1ab8db710 Add support for .NET Framework 4.6.2 in project file
Updated `DigitalData.Core.Infrastructure.csproj` to include .NET Framework version 4.6.2 alongside net7.0, net8.0, and net9.0. Configured framework-specific settings for nullable reference types, implicit usings, and language versions. Added a new `<ItemGroup>` for net462 to reference `Microsoft.EntityFrameworkCore` version 3.1.32.
2025-09-30 18:11:38 +02:00
Developer 02
ca08709d99 Bump version to 1.3.2 in project configuration
Updated the version number, assembly version, and file version in DigitalData.Core.Abstraction.Application.csproj from 1.3.1 to 1.3.2 to reflect the new release of the application.
2025-09-30 17:52:24 +02:00
Developer 02
28e415dee1 Add .NET Framework support in Extensions.cs
Introduce conditional compilation directives for the .NET Framework, including necessary using statements and a modified namespace declaration. Add a closing brace for the class definition to ensure compatibility across different target frameworks.
2025-09-30 17:50:53 +02:00
Developer 02
2cedfbe91b Add conditional compilation for IRepositoryFactory
Updated the namespace declaration in `IRepositoryFactory.cs` to support conditional compilation for .NET and .NET Framework. The `Get<TEntity>()` method now conditionally includes the `public` access modifier based on the target framework. Adjusted the interface structure to ensure proper compilation and organization.
2025-09-30 17:49:26 +02:00
Developer 02
d4d1d2b69f Add conditional compilation for .NET Framework support
Introduce conditional compilation directives in the IRepository interface to support .NET Framework. Update method signatures to conditionally include the `public` access modifier for compatibility across frameworks. Adjust the Entity method to remove the `public` modifier, enhancing flexibility while maintaining existing functionality.
2025-09-30 17:47:24 +02:00
Developer 02
74a625a863 Enhance framework compatibility and code readability
Added preprocessor directives for .NET framework compatibility.
Modified `using` directives to be framework-specific.
Improved code formatting for better readability.
Introduced obsolete attributes for deprecated methods,
recommending `MediatR` as an alternative.
Added XML documentation for clarity and maintainability.
2025-09-30 17:33:51 +02:00
Developer 02
07ab7f0c62 refactor(DataResult): update to execute if NET 2025-09-30 17:03:39 +02:00
Developer 02
e74a740abd refactor(CookieConsentSettings): update to be executed only on NET 2025-09-30 16:57:54 +02:00
Developer 02
dfa3cd1a58 refactor(BaseDto): update to compile only in net 2025-09-30 16:57:05 +02:00
Developer 02
0dd4930f1b refactor(DigitalData.Core.Abstraction.Application): update to support net 462 2025-09-30 16:52:02 +02:00
28 changed files with 591 additions and 315 deletions

View File

@@ -1,4 +1,5 @@
namespace DigitalData.Core.Abstraction.Application.DTO; #if NET
namespace DigitalData.Core.Abstraction.Application.DTO;
/// <summary> /// <summary>
/// Represents a base Data Transfer Object (DTO) with an identifier. /// Represents a base Data Transfer Object (DTO) with an identifier.
@@ -15,3 +16,4 @@ public record BaseDTO<TId>(TId Id) where TId : notnull
/// <returns>A hash code for the current object, derived from the identifier.</returns> /// <returns>A hash code for the current object, derived from the identifier.</returns>
public override int GetHashCode() => Id.GetHashCode(); public override int GetHashCode() => Id.GetHashCode();
} }
#endif

View File

@@ -1,5 +1,6 @@
namespace DigitalData.Core.Abstraction.Application.DTO #if NET
{ namespace DigitalData.Core.Abstraction.Application.DTO;
/// <summary> /// <summary>
/// Represents settings related to user cookie consent dialogs. Designed to be serialized into JSON format for use with JavaScript frontend libraries, /// Represents settings related to user cookie consent dialogs. Designed to be serialized into JSON format for use with JavaScript frontend libraries,
/// such as the bootstrap-cookie-consent-settings at the GitHub repository: https://github.com/shaack/bootstrap-cookie-consent-settings /// such as the bootstrap-cookie-consent-settings at the GitHub repository: https://github.com/shaack/bootstrap-cookie-consent-settings
@@ -71,4 +72,4 @@
/// </summary> /// </summary>
public List<string>? Categories { get; set; } public List<string>? Categories { get; set; }
} }
} #endif

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.Configuration; #if NET
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Configuration; using System.Configuration;
@@ -32,3 +33,4 @@ public static class DIExtensions
return services; return services;
} }
} }
#endif

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging; #if NET
using Microsoft.Extensions.Logging;
using System.Text; using System.Text;
namespace DigitalData.Core.Abstraction.Application.DTO; namespace DigitalData.Core.Abstraction.Application.DTO;
@@ -391,3 +392,4 @@ public static class DTOExtensions
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")] [Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
public static bool IsWrong(this DataResult<bool> bResult) => !bResult.Data; public static bool IsWrong(this DataResult<bool> bResult) => !bResult.Data;
} }
#endif

View File

@@ -1,4 +1,5 @@
using System.Text.Json.Serialization; #if NET
using System.Text.Json.Serialization;
namespace DigitalData.Core.Abstraction.Application.DTO; namespace DigitalData.Core.Abstraction.Application.DTO;
@@ -26,3 +27,4 @@ public class DataResult<T> : Result
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")] [Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
public DataResult<I> ToFail<I>() => Fail<I>().Message(Messages).Notice(Notices); public DataResult<I> ToFail<I>() => Fail<I>().Message(Messages).Notice(Notices);
} }
#endif

View File

@@ -1,4 +1,5 @@
namespace DigitalData.Core.Abstraction.Application.DTO; #if NET
namespace DigitalData.Core.Abstraction.Application.DTO;
/// <summary> /// <summary>
/// Defines flags that indicate specific types of status or conditions in a service operation. /// Defines flags that indicate specific types of status or conditions in a service operation.
@@ -48,3 +49,4 @@ public enum Flag
/// </summary> /// </summary>
NotFound NotFound
} }
#endif

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging; #if NET
using Microsoft.Extensions.Logging;
namespace DigitalData.Core.Abstraction.Application.DTO; namespace DigitalData.Core.Abstraction.Application.DTO;
@@ -26,3 +27,4 @@ public class Notice
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")] [Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
public List<string> Messages { get; init; } = new(); public List<string> Messages { get; init; } = new();
} }
#endif

View File

@@ -1,4 +1,5 @@
using System.Text.Json.Serialization; #if NET
using System.Text.Json.Serialization;
namespace DigitalData.Core.Abstraction.Application.DTO; namespace DigitalData.Core.Abstraction.Application.DTO;
@@ -106,3 +107,4 @@ public class Result
}; };
#pragma warning restore CS8601 // Possible null reference assignment. #pragma warning restore CS8601 // Possible null reference assignment.
} }
#endif

View File

@@ -1,9 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks> <TargetFrameworks>net462;net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Description>This package defines the abstraction layer for the DigitalData.Core.Application module, providing interfaces and contracts for application services, repositories, and infrastructure components in alignment with Clean Architecture principles.</Description> <Description>This package defines the abstraction layer for the DigitalData.Core.Application module, providing interfaces and contracts for application services, repositories, and infrastructure components in alignment with Clean Architecture principles.</Description>
<PackageId>DigitalData.Core.Abstraction.Application</PackageId> <PackageId>DigitalData.Core.Abstraction.Application</PackageId>
@@ -14,9 +12,9 @@
<PackageIcon>core_icon.png</PackageIcon> <PackageIcon>core_icon.png</PackageIcon>
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl> <RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
<PackageTags>digital data core application clean architecture abstraction</PackageTags> <PackageTags>digital data core application clean architecture abstraction</PackageTags>
<Version>1.3.1</Version> <Version>1.3.2</Version>
<AssemblyVersion>1.3.1</AssemblyVersion> <AssemblyVersion>1.3.2</AssemblyVersion>
<FileVersion>1.3.1</FileVersion> <FileVersion>1.3.2</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -26,6 +24,20 @@
</None> </None>
</ItemGroup> </ItemGroup>
<!-- disable for net462 -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<!-- enable for net7 and more -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net7.0' Or '$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net9.0'">
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" /> <PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
@@ -36,6 +48,12 @@
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" /> <PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />

View File

@@ -1,4 +1,5 @@
namespace DigitalData.Core.Abstraction.Application; #if NET
namespace DigitalData.Core.Abstraction.Application;
/// <summary> /// <summary>
/// Provides extension methods for retrieving the value of an 'Id' property from objects. /// Provides extension methods for retrieving the value of an 'Id' property from objects.
@@ -92,3 +93,4 @@ public static class EntityExtensions
return id is not null; return id is not null;
} }
} }
#endif

View File

@@ -1,4 +1,5 @@
namespace DigitalData.Core.Abstraction.Application #if NET
namespace DigitalData.Core.Abstraction.Application
{ {
/// <summary> /// <summary>
/// Implements a simplified CRUD service interface that uses a single Data Transfer Object (DTO) type for all CRUD operations, /// Implements a simplified CRUD service interface that uses a single Data Transfer Object (DTO) type for all CRUD operations,
@@ -19,3 +20,4 @@
{ {
} }
} }
#endif

View File

@@ -1,7 +1,8 @@
using DigitalData.Core.Abstraction.Application.DTO; #if NET
using DigitalData.Core.Abstraction.Application.DTO;
namespace DigitalData.Core.Abstraction.Application;
namespace DigitalData.Core.Abstraction.Application
{
[Obsolete("Use MediatR")] [Obsolete("Use MediatR")]
public interface ICRUDService<TCreateDto, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId> public interface ICRUDService<TCreateDto, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
where TCreateDto : class where TReadDto : class where TEntity : class where TCreateDto : class where TReadDto : class where TEntity : class
@@ -22,4 +23,4 @@ namespace DigitalData.Core.Abstraction.Application
/// <returns>An Result indicating the outcome of the update operation, with an appropriate message.</returns> /// <returns>An Result indicating the outcome of the update operation, with an appropriate message.</returns>
Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto); Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto);
} }
} #endif

View File

@@ -1,8 +1,10 @@
using DigitalData.Core.Abstraction.Application.DTO; #if NET
using DigitalData.Core.Abstraction.Application.DTO;
using System.DirectoryServices; using System.DirectoryServices;
namespace DigitalData.Core.Abstraction.Application namespace DigitalData.Core.Abstraction.Application;
{
[Obsolete("Use DigitalData.ActiveDirectory")]
public interface IDirectorySearchService public interface IDirectorySearchService
{ {
public string ServerName { get; } public string ServerName { get; }
@@ -91,4 +93,4 @@ namespace DigitalData.Core.Abstraction.Application
/// <returns>The cached <see cref="DirectoryEntry"/> if found; otherwise, null.</returns> /// <returns>The cached <see cref="DirectoryEntry"/> if found; otherwise, null.</returns>
DirectoryEntry? GetSearchRootCache(string username); DirectoryEntry? GetSearchRootCache(string username);
} }
} #endif

View File

@@ -1,9 +1,10 @@
using Microsoft.IdentityModel.Tokens; #if NET
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography; using System.Security.Cryptography;
namespace DigitalData.Core.Abstraction.Application namespace DigitalData.Core.Abstraction.Application;
{
/// <summary> /// <summary>
/// Defines the operations for JWT service handling claims of type <typeparamref name="TClaimValue"/>. /// Defines the operations for JWT service handling claims of type <typeparamref name="TClaimValue"/>.
/// </summary> /// </summary>
@@ -38,4 +39,4 @@ namespace DigitalData.Core.Abstraction.Application
/// <returns>A <see cref="JwtSecurityToken"/> if the token is valid; otherwise, null.</returns> /// <returns>A <see cref="JwtSecurityToken"/> if the token is valid; otherwise, null.</returns>
JwtSecurityToken? ReadSecurityToken(string token); JwtSecurityToken? ReadSecurityToken(string token);
} }
} #endif

View File

@@ -1,7 +1,8 @@
using DigitalData.Core.Abstraction.Application.DTO; #if NET
using DigitalData.Core.Abstraction.Application.DTO;
namespace DigitalData.Core.Abstraction.Application;
namespace DigitalData.Core.Abstraction.Application
{
[Obsolete("Use MediatR")] [Obsolete("Use MediatR")]
public interface IReadService<TReadDto, TEntity, TId> public interface IReadService<TReadDto, TEntity, TId>
where TReadDto : class where TEntity : class where TReadDto : class where TEntity : class
@@ -36,4 +37,4 @@ namespace DigitalData.Core.Abstraction.Application
/// <returns>A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns> /// <returns>A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
Task<bool> HasEntity(TId id); Task<bool> HasEntity(TId id);
} }
} #endif

View File

@@ -1,7 +1,19 @@
using System.Linq.Expressions; using System.Linq.Expressions;
using DigitalData.Core.Abstractions.Interfaces; using DigitalData.Core.Abstractions.Interfaces;
#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
#endif
namespace DigitalData.Core.Abstraction.Application.Repository; namespace DigitalData.Core.Abstraction.Application.Repository
#if NET
;
#elif NETFRAMEWORK
{
#endif
public static class Extensions public static class Extensions
{ {
@@ -61,3 +73,7 @@ public static class Extensions
#endregion #endregion
#endregion #endregion
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -1,4 +1,5 @@
namespace DigitalData.Core.Abstraction.Application.Repository #if NET
namespace DigitalData.Core.Abstraction.Application.Repository
{ {
/// <summary> /// <summary>
/// Defines the contract for CRUD operations on a repository for entities of type TEntity. /// Defines the contract for CRUD operations on a repository for entities of type TEntity.
@@ -61,3 +62,4 @@
Task<int> CountAsync(TId id); Task<int> CountAsync(TId id);
} }
} }
#endif

View File

@@ -1,4 +1,7 @@
namespace DigitalData.Core.Abstraction.Application.Repository #if NETFRAMEWORK
using System.Collections.Generic;
#endif
namespace DigitalData.Core.Abstraction.Application.Repository
{ {
/// <summary> /// <summary>
/// Defines methods for mapping between entities and Data Transfer Objects (DTOs). /// Defines methods for mapping between entities and Data Transfer Objects (DTOs).

View File

@@ -1,50 +1,105 @@
using DigitalData.Core.Abstractions.Interfaces; using DigitalData.Core.Abstractions.Interfaces;
using System.Linq.Expressions; using System.Linq.Expressions;
#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
#endif
namespace DigitalData.Core.Abstraction.Application.Repository; namespace DigitalData.Core.Abstraction.Application.Repository
#if NET
;
#elif NETFRAMEWORK
{
#endif
public interface IRepository<TEntity> public interface IRepository<TEntity>
{ {
#region Create #region Create
public Task<TEntity> CreateAsync(TEntity entity, CancellationToken cancel = default); #if NET
public
#endif
Task<TEntity> CreateAsync(TEntity entity, CancellationToken cancel = default);
public Task<IEnumerable<TEntity>> CreateAsync(IEnumerable<TEntity> entities, CancellationToken cancel = default); #if NET
public
#endif
Task<IEnumerable<TEntity>> CreateAsync(IEnumerable<TEntity> entities, CancellationToken cancel = default);
public Task<TEntity> CreateAsync<TDto>(TDto dto, CancellationToken cancel = default); #if NET
public
#endif
Task<TEntity> CreateAsync<TDto>(TDto dto, CancellationToken cancel = default);
public Task<IEnumerable<TEntity>> CreateAsync<TDto>(IEnumerable<TDto> dtos, CancellationToken cancel = default); #if NET
public
#endif
Task<IEnumerable<TEntity>> CreateAsync<TDto>(IEnumerable<TDto> dtos, CancellationToken cancel = default);
#endregion Create #endregion Create
#region Read #region Read
public IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> expression); #if NET
public
#endif
IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> expression);
public IEnumerable<TEntity> GetAll(); #if NET
public
#endif
IEnumerable<TEntity> GetAll();
public Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancel = default); #if NET
public
#endif
Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancel = default);
#endregion Read #endregion Read
#region Update #region Update
public Task UpdateAsync<TDto>(TDto dto, Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default); #if NET
public
#endif
Task UpdateAsync<TDto>(TDto dto, Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default);
public Task UpdateAsync<TDto>(TDto dto, Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default); #if NET
public
#endif
Task UpdateAsync<TDto>(TDto dto, Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default);
#endregion Update #endregion Update
#region Delete #region Delete
public Task DeleteAsync(Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default); #if NET
public
#endif
Task DeleteAsync(Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default);
public Task DeleteAsync(Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default); #if NET
public
#endif
Task DeleteAsync(Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default);
#endregion Delete #endregion Delete
#region Obsolete #region Obsolete
[Obsolete("Use CreateAsync, UpdateAsync or DeleteAsync")] [Obsolete("Use CreateAsync, UpdateAsync or DeleteAsync")]
public IQueryable<TEntity> Read(); #if NET
public
#endif
IQueryable<TEntity> Read();
[Obsolete("Use IRepository<TEntity>.Where")] [Obsolete("Use IRepository<TEntity>.Where")]
public IQueryable<TEntity> ReadOnly(); #if NET
public
#endif
IQueryable<TEntity> ReadOnly();
#endregion #endregion
} }
public interface IRepository public interface IRepository
{ {
public IRepository<TEntity> Entity<TEntity>() where TEntity : IEntity; IRepository<TEntity> Entity<TEntity>() where TEntity : IEntity;
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -1,6 +1,18 @@
namespace DigitalData.Core.Abstraction.Application.Repository; namespace DigitalData.Core.Abstraction.Application.Repository
#if NET
;
#elif NETFRAMEWORK
{
#endif
public interface IRepositoryFactory public interface IRepositoryFactory
{ {
public IRepository<TEntity> Get<TEntity>(); #if NET
public
#endif
IRepository<TEntity> Get<TEntity>();
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -21,6 +21,12 @@
<FileVersion>4.1.1</FileVersion> <FileVersion>4.1.1</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="..\Assets\core_icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<!-- disable for net462 --> <!-- disable for net462 -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'"> <PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
@@ -36,13 +42,6 @@
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="..\..\nuget-package-icons\core_icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" /> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />

View File

@@ -1,4 +1,5 @@
using DigitalData.Core.Abstraction.Application; #if NET
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -111,3 +112,4 @@ namespace DigitalData.Core.Infrastructure
public virtual async Task<int> CountAsync(TId id) => await _dbSet.Where(e => e.GetId().Equals(id)).CountAsync(); public virtual async Task<int> CountAsync(TId id) => await _dbSet.Where(e => e.GetId().Equals(id)).CountAsync();
} }
} }
#endif

View File

@@ -4,8 +4,20 @@ using DigitalData.Core.Abstractions.Interfaces;
using DigitalData.Core.Infrastructure.Factory; using DigitalData.Core.Infrastructure.Factory;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions; using System.Linq.Expressions;
#if NETFRAMEWORK
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
#endif
namespace DigitalData.Core.Infrastructure; namespace DigitalData.Core.Infrastructure
#if NET
;
#elif NETFRAMEWORK
{
#endif
public class DbRepository<TDbContext, TEntity> : IRepository<TEntity> where TDbContext : DbContext where TEntity : class public class DbRepository<TDbContext, TEntity> : IRepository<TEntity> where TDbContext : DbContext where TEntity : class
{ {
@@ -13,9 +25,17 @@ public class DbRepository<TDbContext, TEntity> : IRepository<TEntity> where TDbC
protected internal readonly DbSet<TEntity> Entities; protected internal readonly DbSet<TEntity> Entities;
public IMapper? Mapper { get; } public IMapper
#if NET
?
#endif
Mapper { get; }
public DbRepository(TDbContext context, DbSetFactory<TDbContext, TEntity> factory, IMapper? mapper = null) public DbRepository(TDbContext context, DbSetFactory<TDbContext, TEntity> factory, IMapper
#if NET
?
#endif
mapper = null)
{ {
Context = context; Context = context;
Entities = factory.Create(context); Entities = factory.Create(context);
@@ -37,10 +57,19 @@ public class DbRepository<TDbContext, TEntity> : IRepository<TEntity> where TDbC
return entities; return entities;
} }
public virtual Task<TEntity> CreateAsync<TDto>(TDto dto, CancellationToken cancel = default) => CreateAsync(Mapper!.Map<TEntity>(dto), cancel); public virtual Task<TEntity> CreateAsync<TDto>(TDto dto, CancellationToken cancel = default)
=> CreateAsync(Mapper
#if NET
!
#endif
.Map<TEntity>(dto), cancel);
public virtual Task<IEnumerable<TEntity>> CreateAsync<TDto>(IEnumerable<TDto> dtos, CancellationToken cancel = default) public virtual Task<IEnumerable<TEntity>> CreateAsync<TDto>(IEnumerable<TDto> dtos, CancellationToken cancel = default)
=> CreateAsync(Mapper!.Map<IEnumerable<TEntity>>(dtos), cancel); => CreateAsync(Mapper
#if NET
!
#endif
.Map<IEnumerable<TEntity>>(dtos), cancel);
#endregion Create #endregion Create
#region Read #region Read
@@ -60,7 +89,11 @@ public class DbRepository<TDbContext, TEntity> : IRepository<TEntity> where TDbC
for (int i = entities.Count - 1; i >= 0; i--) for (int i = entities.Count - 1; i >= 0; i--)
{ {
Mapper!.Map(dto, entities[i]); Mapper
#if NET
!
#endif
.Map(dto, entities[i]);
Entities.Update(entities[i]); Entities.Update(entities[i]);
} }
@@ -104,3 +137,7 @@ public class DbRepository : IRepository
public IRepository<TEntity> Entity<TEntity>() where TEntity : IEntity => _factory.Get<TEntity>(); public IRepository<TEntity> Entity<TEntity>() where TEntity : IEntity => _factory.Get<TEntity>();
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -4,8 +4,18 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection; using System.Reflection;
#if NETFRAMEWORK
using System.Collections.Generic;
using System;
using System.Linq;
#endif
namespace DigitalData.Core.Infrastructure; namespace DigitalData.Core.Infrastructure
#if NET
;
#elif NETFRAMEWORK
{
#endif
public static class DependencyInjection public static class DependencyInjection
{ {
@@ -28,13 +38,13 @@ public static class DependencyInjection
public class RepositoryConfiguration public class RepositoryConfiguration
{ {
// 1. register from assembly // 1. register from assembly
private readonly Queue<Action<IServiceCollection>> RegsFromAssembly = new(); private readonly Queue<Action<IServiceCollection>> RegsFromAssembly = new Queue<Action<IServiceCollection>>();
// 2. register entities (can overwrite) // 2. register entities (can overwrite)
private readonly Queue<Action<IServiceCollection>> RegsEntity = new(); private readonly Queue<Action<IServiceCollection>> RegsEntity = new Queue<Action<IServiceCollection>>();
// 3. register db set factories (can overwrite) // 3. register db set factories (can overwrite)
private readonly Queue<Action<IServiceCollection>> RegsDbSetFactory = new(); private readonly Queue<Action<IServiceCollection>> RegsDbSetFactory = new Queue<Action<IServiceCollection>>();
internal void RegisterAllServices(IServiceCollection services) internal void RegisterAllServices(IServiceCollection services)
{ {
@@ -76,7 +86,11 @@ public static class DependencyInjection
.GetMethod(nameof(AddDbSetFactory), .GetMethod(nameof(AddDbSetFactory),
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
var genericMethod = addDbSetFactoryMethod!.MakeGenericMethod(typeof(TDbContext), entityType); var genericMethod = addDbSetFactoryMethod
#if NET
!
#endif
.MakeGenericMethod(typeof(TDbContext), entityType);
genericMethod.Invoke(null, new [] { services, null }); genericMethod.Invoke(null, new [] { services, null });
#endregion DbSetFactory #endregion DbSetFactory
} }
@@ -85,7 +99,11 @@ public static class DependencyInjection
RegsFromAssembly.Enqueue(reg); RegsFromAssembly.Enqueue(reg);
} }
public void RegisterEntity<TDbContext, TEntity>(Func<TDbContext, DbSet<TEntity>>? dbSetFactory = null) public void RegisterEntity<TDbContext, TEntity>(Func<TDbContext, DbSet<TEntity>>
#if NET
?
#endif
dbSetFactory = null)
where TDbContext : DbContext where TDbContext : DbContext
where TEntity : class where TEntity : class
{ {
@@ -109,12 +127,25 @@ public static class DependencyInjection
queue.Dequeue().Invoke(services); queue.Dequeue().Invoke(services);
} }
internal static IServiceCollection AddDbSetFactory<TDbContext, TEntity>(this IServiceCollection services, Func<TDbContext, DbSet<TEntity>>? create = null) internal static IServiceCollection AddDbSetFactory<TDbContext, TEntity>(this IServiceCollection services, Func<TDbContext, DbSet<TEntity>>
#if NET
?
#endif
create = null)
where TDbContext : DbContext where TDbContext : DbContext
where TEntity : class where TEntity : class
{ {
#if NET
create ??= ctx => ctx.Set<TEntity>(); create ??= ctx => ctx.Set<TEntity>();
#elif NETFRAMEWORK
if(create is null)
create = ctx => ctx.Set<TEntity>();
#endif
services.AddSingleton(_ => new DbSetFactory<TDbContext, TEntity>(create)); services.AddSingleton(_ => new DbSetFactory<TDbContext, TEntity>(create));
return services; return services;
} }
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -1,9 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks> <TargetFrameworks>net462;net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>DigitalData.Core.Infrastructure</PackageId> <PackageId>DigitalData.Core.Infrastructure</PackageId>
<Authors>Digital Data GmbH</Authors> <Authors>Digital Data GmbH</Authors>
@@ -15,9 +13,9 @@
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl> <RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
<RepositoryType>digital data core abstractions clean architecture</RepositoryType> <RepositoryType>digital data core abstractions clean architecture</RepositoryType>
<PackageTags>digital data core infrastructure clean architecture</PackageTags> <PackageTags>digital data core infrastructure clean architecture</PackageTags>
<Version>2.4.1</Version> <Version>2.4.2</Version>
<AssemblyVersion>2.4.1</AssemblyVersion> <AssemblyVersion>2.4.2</AssemblyVersion>
<FileVersion>2.4.1</FileVersion> <FileVersion>2.4.2</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -27,6 +25,24 @@
</None> </None>
</ItemGroup> </ItemGroup>
<!-- disable for net462 -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<!-- enable for net7 and more -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net7.0' Or '$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net9.0'">
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.32" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
</ItemGroup> </ItemGroup>

View File

@@ -1,7 +1,15 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
#if NETFRAMEWORK
using System;
#endif
namespace DigitalData.Core.Infrastructure.Factory; namespace DigitalData.Core.Infrastructure.Factory
#if NET
;
#elif NETFRAMEWORK
{
#endif
public class DbRepositoryFactory : IRepositoryFactory public class DbRepositoryFactory : IRepositoryFactory
{ {
@@ -14,3 +22,7 @@ public class DbRepositoryFactory : IRepositoryFactory
public IRepository<TEntity> Get<TEntity>() => _provider.GetRequiredService<IRepository<TEntity>>(); public IRepository<TEntity> Get<TEntity>() => _provider.GetRequiredService<IRepository<TEntity>>();
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -1,6 +1,14 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
#if NETFRAMEWORK
using System;
#endif
namespace DigitalData.Core.Infrastructure.Factory; namespace DigitalData.Core.Infrastructure.Factory
#if NET
;
#elif NETFRAMEWORK
{
#endif
public class DbSetFactory<TDbContext,TEntity> where TDbContext : DbContext where TEntity : class public class DbSetFactory<TDbContext,TEntity> where TDbContext : DbContext where TEntity : class
{ {
@@ -11,3 +19,7 @@ public class DbSetFactory<TDbContext,TEntity> where TDbContext : DbContext where
Create = create; Create = create;
} }
} }
#if NETFRAMEWORK
}
#endif

View File

@@ -0,0 +1,37 @@
#if NETFRAMEWORK
using System;
#endif
using DigitalData.Core.Abstraction.Application.Repository;
using Microsoft.Extensions.DependencyInjection;
namespace DigitalData.Core.Infrastructure
#if NET
;
#elif NETFRAMEWORK
{
#endif
public static class Static
{
private readonly static Lazy<IServiceCollection> LazyServices = new Lazy<IServiceCollection>(() => new ServiceCollection());
public static IServiceCollection Services => LazyProvider.IsValueCreated
? LazyServices.Value
: throw new InvalidOperationException("Services cannot be accessed after the Provider has been created.");
private static readonly Lazy<IServiceProvider> LazyProvider = new Lazy<IServiceProvider>(Services.BuildServiceProvider);
public static IServiceProvider Provider => LazyProvider.Value;
public static IRepository Repository => Provider.GetRequiredService<IRepository>();
}
public static class Static<TEntity>
{
public static IRepository<TEntity> Repository() => Static.Provider.GetRequiredService<IRepository<TEntity>>();
}
#if NETFRAMEWORK
}
#endif