Muslim.GenericService 10.0.1

dotnet add package Muslim.GenericService --version 10.0.1
                    
NuGet\Install-Package Muslim.GenericService -Version 10.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Muslim.GenericService" Version="10.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Muslim.GenericService" Version="10.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Muslim.GenericService" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Muslim.GenericService --version 10.0.1
                    
#r "nuget: Muslim.GenericService, 10.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Muslim.GenericService@10.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Muslim.GenericService&version=10.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Muslim.GenericService&version=10.0.1
                    
Install as a Cake Tool

Muslim.GenericService

A generic service layer for .NET 10 on top of Muslim.GenericRepository. One class, Service<TEntity>, gives every table reads, DTO projection, paging with Muslim.Filter, create and update with validation, soft delete and restore, bulk deletes and counts, and returns a Muslim.Result Result<T> instead of throwing.

dotnet add package Muslim.GenericService
dotnet add package Muslim.GenericRepository

This package depends on the repository interface only; add Muslim.GenericRepository (or your own IRepository<T> implementation) to the application.

The service contract, IService<TEntity> and the interfaces it combines, is in Muslim.GenericService.Interface, which comes with this package. Projects that only call services (controllers, other libraries) can reference that package alone. The namespaces are Muslim.GenericService and Muslim.GenericService.Interfaces.

Full documentation: genericservice.netlify.app

Quick start

Set up the repository as its README describes (DbContext, AutoMapper, ICurrentUser, BaseRepository.SetDbContext<T>(), and InjectExtensions.SetServiceProvider at startup and per request). Then register validators and the generic types:

using FluentValidation;
using Muslim.GenericRepository.Interface;
using Muslim.GenericRepository.Repositories;
using Muslim.GenericService;

builder.Services.AddValidatorsFromAssemblyContaining<NoteDtoValidator>();
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
builder.Services.AddScoped(typeof(IService<>), typeof(Service<>));

Inject IService<Note> and use it:

public class NotesController(IService<Note> notes) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Create(NoteDto request)
    {
        var result = await notes.CreateAsync(request);   // validated, inserted, Id filled
        return result.IsSuccess ? Ok(result) : BadRequest(result);
    }
}

For a service with its own methods, derive from Service<T> and pass the repository to the base constructor. AddAutoInjection registers it:

public interface INoteService : IService<Note>
{
    Task<int> CountArchivedAsync();
}

public class NoteService(INoteRepository repository) : Service<Note>(repository), INoteService
{
    public Task<int> CountArchivedAsync() => CountAsync(x => x.IsDeleted);
}

What you get back

Member Meaning
IsSuccess The call worked. A missing row from GetById/FirstOrDefault/SingleOrDefault is still a success with Response == null.
Response The value.
Error Exception messages, or one message per failed item in range operations.
ValidatorError Property name and message for each validation failure.
Page Count (all matching rows), PageSize, NumberOfPages for Find*.

Any, Count, ExecuteSql* and FromSqlInterpolated return plain values: -1 (or false, null) on error.

Validation

Create* and Update* validate DTOs with FluentValidation through Muslim.Validator before writing. Register a validator for every DTO you pass, even an empty one; a DTO with no validator fails validation. Validators are resolved from the current Muslim.Inject scope (the per-request provider), so scoped validators work. Without one, the provider given to ValidateResult.SetServiceProvider is used. CreateAsync(TEntity) does not validate.

Paging

Find(filter) and Find<TDto>(filter) with a Muslim.Filter IFilter<TEntity> return one page, and Page.Count is the number of all matching rows. The overloads that take a condition and a pageSize return every match; pageSize only fills Page.NumberOfPages.

Good to know

  • Every write commits on its own. For several writes in one transaction, use the repositories' staging methods and one Save().
  • FirstOrDefaultAsync<TDto>(x => ...), SingleOrDefault<TDto>(x => ...) and SingleOrDefaultAsync<TDto>(x => ...) are ambiguous (CS0121) when the entity and the DTO share the property. Type the parameter: (Note x) => x.Title == title.
  • DeleteRangeByIdsAsync and SoftDeleteRange* handle each item separately: successes in Response, failures in Error.
  • All public methods are virtual. Async methods do not take a CancellationToken.
  • Service<TEntity> is a partial class split by concern (Services/Read, Services/Write, Services/SqlOperations), like Repository<TEntity>.

The full behavior of every method, with examples and troubleshooting, is in the agent guide that ships in this package (skills/muslim-genericservice/), readable as plain Markdown.

Coding-agent guidance

The package contains a short guide for AI coding agents: an Agent Skills SKILL.md and two reference files under skills/muslim-genericservice/ in the .nupkg. It describes this version's API, setup and pitfalls, so an agent can use the package without reading its source. A buildTransitive/Muslim.GenericService.targets file copies it into your repository.

Where and when it appears

  • When a project that references Muslim.GenericService (directly, or through another package or project) builds, the guide is copied to .agents/skills/muslim-genericservice/ at the repository root. Installing or restoring alone does nothing; the files appear after the first build, from the command line or an IDE.
  • The repository root is the nearest folder above the project that contains .git (a folder, or a file for worktrees and submodules). Without one, the nearest folder with a .sln or .slnx file is used, and failing that the project's own folder. The current working directory does not matter.
  • Design-time builds (IDE background analysis) do not write files.
  • Next to the guide the build writes package-version.txt (the version it belongs to), .muslim-genericservice.manifest (which files the package owns, with their hashes) and .muslim-genericservice.lock. Commit the folder or add it to .gitignore, as you prefer.

Which agents read it

.agents/skills/ is a shared, project-level skills location. Agents documented or reported to read it include OpenAI Codex, GitHub Copilot in VS Code, Gemini CLI, Cursor and OpenCode. Support depends on the agent and its version; check your agent's documentation. The package was not tested against each agent.

Claude Code does not read .agents/skills/; it reads .claude/skills/. To use the guide there, copy or link the folder to .claude/skills/muslim-genericservice/, or mention it in CLAUDE.md.

Most agents look for skills when a session starts. Start a new agent session after the first build (and after an upgrade); a session that is already running may not see the guide.

Your files are kept

  • Files you add to the folder, files you edit, other skills, and AGENTS.md are never overwritten or deleted. An edited file stops being updated and the build warns (MGSSKILL003).
  • An existing muslim-genericservice skill that the package did not create is left alone (MGSSKILL003).
  • If anything blocks writing (read-only checkout, a file where a folder should be, a damaged manifest), the build warns (MGSSKILL001) and continues. The guide never fails a build.

Upgrades and version conflicts

  • When the package version changes, the next build replaces the files the package owns that you have not edited, and removes owned files the new version no longer ships (edited ones are kept).
  • If projects in one repository use different versions, the folder keeps the highest version's guide. A project on an older version leaves it untouched and warns (MGSSKILL002). Align the versions to clear the warning.
  • Two different payloads published under the same version are not mixed; the installed one is kept and the build warns (MGSSKILL002).
  • Downgrading every project does not roll the guide back; delete the folder and build again.
  • Parallel builds, several projects and several target frameworks write the folder one at a time (file lock) and do not conflict. Repeated builds do not rewrite unchanged files.

Removing it

Removing the package stops future updates but does not delete .agents/skills/muslim-genericservice/; delete the folder yourself. dotnet clean does not remove it either.

Turning it off

In the project file or in Directory.Build.props (for the whole repository):

<PropertyGroup>
  <MuslimGenericServiceGenerateSkill>false</MuslimGenericServiceGenerateSkill>
</PropertyGroup>

or build with -p:MuslimGenericServiceGenerateSkill=false. Files already written are kept. The switch affects only this package's guide. Other Muslim packages that ship a guide (for example Muslim.Inject and Muslim.Validator, which arrive with this one) write their own folders and have their own switches.

Other limitations

  • Builds that skip the Build target (dotnet restore alone, tools that only evaluate projects) do not write the guide.
  • The copy step uses MSBuild's RoslynCodeTaskFactory, which compiles a small task the first time each build process runs it.
  • packages.config projects do not import buildTransitive files; use PackageReference.
Package Use it for
Muslim.GenericService.Interface The service interfaces
Muslim.GenericRepository The repository implementation
Muslim.GenericRepository.Interface The repository interfaces
Muslim.Result Result<T>
Muslim.Validator DTO validation
Muslim.Filter Filtering, sorting and paging
Muslim.Inject Automatic dependency registration

License

See LICENSE.txt.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Muslim.GenericService:

Package Downloads
Muslim.LogInformation.Application

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.1 97 10/15/2026
8.0.0 161 9/23/2026
2.3.0 130 8/10/2026
2.2.7 125 8/10/2026
2.2.5 248 1/19/2025
2.2.4 182 1/17/2025

IService<TEntity> and its part interfaces moved to the new Muslim.GenericService.Interface package (same namespaces, type-forwarded); Service<TEntity> is split into partial files. Find(filter)/FindAsync(filter) no longer fail with "Missing map from X to X"; FindAsync page counts now count matching rows instead of the whole table; FindAsync(condition) returns a failed Result instead of throwing; DeleteRangeByIdsAsync and SoftDeleteRange* no longer report success as failure or carry a spurious "not found" error; CreateRange/CreateRangeAsync catch database errors; UpdateRange/UpdateRangeAsync enumerate once and detach every saved row; DTO validation uses the current Muslim.Inject request scope; a missing repository gives a descriptive error. Ships version-matched agent guidance and generates .agents/skills/muslim-genericservice during normal consuming builds; preserves user files and supports MuslimGenericServiceGenerateSkill=false. See CHANGELOG.md and README.md.