{"id":15783320,"url":"https://github.com/msx752/sampledotnet.repositoryfactory","last_synced_at":"2025-03-31T16:49:34.571Z","repository":{"id":84587840,"uuid":"606578452","full_name":"msx752/SampleDotnet.RepositoryFactory","owner":"msx752","description":"Simplifies EF Core data access and transaction management for .NET applications.","archived":false,"fork":false,"pushed_at":"2024-09-08T22:01:47.000Z","size":244,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-19T13:11:19.127Z","etag":null,"topics":["dotnetcore","efcore-dotnetcore","factory-pattern","repositorypattern","unitofwork"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msx752.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-25T22:49:34.000Z","updated_at":"2024-09-07T18:22:11.000Z","dependencies_parsed_at":"2024-09-06T04:35:30.765Z","dependency_job_id":null,"html_url":"https://github.com/msx752/SampleDotnet.RepositoryFactory","commit_stats":{"total_commits":18,"total_committers":1,"mean_commits":18.0,"dds":0.0,"last_synced_commit":"54597cb47dc803ddd92ed193e08b45e3a4afd8e5"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msx752%2FSampleDotnet.RepositoryFactory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msx752%2FSampleDotnet.RepositoryFactory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msx752%2FSampleDotnet.RepositoryFactory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msx752%2FSampleDotnet.RepositoryFactory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msx752","download_url":"https://codeload.github.com/msx752/SampleDotnet.RepositoryFactory/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246500354,"owners_count":20787678,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnetcore","efcore-dotnetcore","factory-pattern","repositorypattern","unitofwork"],"created_at":"2024-10-04T19:41:18.760Z","updated_at":"2025-03-31T16:49:34.551Z","avatar_url":"https://github.com/msx752.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Nuget](https://img.shields.io/badge/package-SampleDotnet.RepositoryFactory-brightgreen.svg?maxAge=259200)](https://www.nuget.org/packages/SampleDotnet.RepositoryFactory)\n[![CodeQL](https://github.com/msx752/SampleDotnet.RepositoryFactory/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/msx752/SampleDotnet.RepositoryFactory/actions/workflows/codeql.yml)\n[![MIT](https://img.shields.io/badge/License-MIT-blue.svg?maxAge=259200)](https://github.com/msx752/SampleDotnet.RepositoryFactory/blob/master/LICENSE.md)\n\n# **SampleDotnet.RepositoryFactory Documentation**\n\n## **Overview**\n\nThe **SampleDotnet.RepositoryFactory** NuGet package provides a robust and flexible solution for managing data access using Entity Framework Core (EF Core) in .NET applications. It leverages the **Repository Pattern** and **Unit of Work Pattern** to ensure efficient database operations, transaction management, and better separation of concerns. This package simplifies working with multiple `DbContext` instances and supports parallel operations using transient scoped `DbContexts` managed by a `DbContextFactory`.\n\n\u003e **Note**: Most features in this package are currently in a preview version. While the package is stable for general use, some features may still be undergoing testing and improvements. Please provide feedback and report any issues to help us enhance the package further.\n\n## **Key Features**\n\n- **Repository Pattern**: Provides generic repositories to manage entities with CRUD operations.\n- **Unit of Work Pattern**: Encapsulates transaction management and ensures all operations are completed or rolled back together.\n- **DbContextFactory**: Supports transient scoped `DbContexts` to prevent concurrency issues.\n- **Automatic Property Management**: Automatically updates `CreatedAt` and `UpdatedAt` properties for entities implementing `IHasDateTimeOffset`.\n- **Flexible Service Lifetimes**: Supports configuring services with various lifetimes (Scoped, Transient, Singleton) to suit different application needs.\n\n## **Installation**\n\nTo install the **SampleDotnet.RepositoryFactory** NuGet package, run the following command in the **Package Manager Console**:\n\n```shell\nInstall-Package SampleDotnet.RepositoryFactory -Pre\n```\n\nOr use the **.NET CLI**:\n\n```shell\ndotnet add package SampleDotnet.RepositoryFactory --prerelease\n```\n\n### **Prerequisites**\n\nEnsure that your project targets one of the following frameworks: **.NET 6.0**, **.NET 7.0**, or **.NET 8.0**. This package does not support .NET 5.\n\n### **1. Parallel Operations and DbContextFactory**\n\nThe package supports parallel operations by using a `DbContextFactory` to create new `DbContext` instances. This approach prevents concurrency issues that occur when the same `DbContext` instance is used across multiple threads.\n\n## **Special Note on Transaction Management**\n\n\u003e **IMPORTANT**: Proper transaction management is crucial when working with multiple `DbContext` instances.\n\n### **Key Points to Consider:**\n\n- **Using Multiple DbContexts**: If you are using multiple `DbContext` instances, each managing its own transaction, be aware that if a transaction commits successfully on one `DbContext` but fails on another, it rolls back already committed transactions to maintain data consistency (Compensate Transaction). This scenario requires careful handling to ensure that all related changes are either fully committed or completely rolled back across all DbContexts.\n\n- **Using a Single DbContext**: When using a single `DbContext` instance for all operations within a unit of work, transaction management is simplified. All operations are either committed together or rolled back together, eliminating the need to manually roll back already committed transactions from different `DbContext` instances.\n\n### **Best Practice**: To avoid the complexity of handling multiple transactions, use a single `DbContext` instance within the scope of a unit of work whenever possible. This approach ensures straightforward transaction management and helps maintain data integrity.\n\n## **Usage**\n\n### **2. Service Registration**\n\nTo use the `RepositoryFactory` and `UnitOfWork` in your application, register the necessary services in the `Startup` class or wherever you configure services in your application.\n\n#### **Example: Configuring Services in ASP.NET Core**\n\n```csharp\npublic void ConfigureServices(IServiceCollection services)\n{\n    // Add DbContextFactory for UserDbContext with the desired lifetime\n    services.AddDbContextFactory\u003cUserDbContext\u003e(options =\u003e\n    {\n        options.UseSqlServer(Configuration.GetConnectionString(\"DefaultConnection\"));\n    });\n\n    // Add repository factory with a specified service lifetime \"Scoped or Transient (especially for the Consumers)\"\n    services.AddRepositoryFactory(ServiceLifetime.Scoped);\n\n    // Additional service registrations...\n}\n```\n\nThis setup uses the traditional `AddDbContextFactory` method to configure `DbContextFactory` for `UserDbContext` and specifies the desired service lifetime for the factory.\n\n### **3. Using the Repository and Unit of Work in Controllers**\n\nAfter configuring the services, use the `IUnitOfWork` and repository pattern in your controllers to manage database operations.\n\n#### **Example: UserController**\n\n```csharp\npublic class UserController : Controller\n{\n    private readonly IUnitOfWork _unitOfWork;\n\n    public UserController(IUnitOfWork unitOfWork)\n    {\n        _unitOfWork = unitOfWork;\n    }\n\n    [HttpDelete(\"{id}\")]\n    public ActionResult Delete(Guid id)\n    {\n        using (var repository = _unitOfWork.CreateRepository\u003cUserDbContext\u003e())\n        {\n            var user = repository.FirstOrDefault\u003cUserEntity\u003e(u =\u003e u.Id == id);\n\n            // Perform operations on the entity...\n\n            repository.Delete(user);\n\n            // Additional operations...\n        }\n\n        _unitOfWork.SaveChanges();\n        return Ok();\n    }\n}\n```\n\n### **4. Automatic Timestamps for Entities**\n\nIf your entities implement the `IHasDateTimeOffset` interface, their `CreatedAt` and `UpdatedAt` properties will be automatically managed when using repository methods.\n\n#### **Example: TestUserEntity**\n\n```csharp\npublic class TestUserEntity : IHasDateTimeOffset\n{\n    [Key]\n    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n    public Guid Id { get; set; }\n\n    public string Name { get; set; }\n    public string Surname { get; set; }\n\n    public DateTimeOffset? CreatedAt { get; set; }\n    public DateTimeOffset? UpdatedAt { get; set; }\n}\n```\n\n\n## **Descriptions of Key Components**\n\n### **IUnitOfWork Interface**\n\nThe `IUnitOfWork` interface defines methods for managing database transactions and repositories:\n- **`CreateRepository\u003cTDbContext\u003e()`**: Creates a new repository for the specified `DbContext`.\n- **`SaveChanges()`**: Commits all pending changes to the database.\n- **`SaveChangesAsync()`**: Asynchronously commits all pending changes to the database.\n- **`IsDbConcurrencyExceptionThrown`**: Indicates if a concurrency exception occurred.\n- **`SaveChangesException`**: Provides details about any exception thrown during the save operation.\n\n### **Repository\u003cTDbContext\u003e Class**\n\nA generic repository class that provides CRUD operations and additional methods for querying and manipulating entities:\n- **`AsQueryable\u003cT\u003e()`**: Returns an `IQueryable` for the specified entity type.\n- **`Delete\u003cT\u003e()`**: Deletes an entity.\n- **`Find\u003cT\u003e()` and `FindAsync\u003cT\u003e()`**: Finds entities by primary key values.\n- **`Insert\u003cT\u003e()` and `InsertAsync\u003cT\u003e()`**: Inserts new entities.\n- **`Update\u003cT\u003e()`**: Updates entities.\n\n### **DbContextFactory and Service Lifetimes**\n\nThe `DbContextFactory` can now be configured with different lifetimes (Scoped, Transient, Singleton) based on your application's needs. Using a transient lifetime is particularly useful for avoiding concurrency issues in multi-threaded environments.\n\n### **Transaction Management**\n\nThe `UnitOfWork` and `TransactionManager` handle transaction management, ensuring that all operations within a unit of work are either committed or rolled back together.\n\n## **Best Practices**\n\n- **Use Scoped or Transient Services**: Use scoped or transient services for the `UnitOfWork` and related services depending on your application's concurrency requirements.\n- **Avoid Long-Running Operations**: Keep the `DbContext` lifespan short to avoid holding resources longer than necessary.\n- **Handle Exceptions Gracefully**: Use `IsDbConcurrencyExceptionThrown` and `SaveChangesException` to handle concurrency and other exceptions effectively.\n\n## **Conclusion**\n\nThe **SampleDotnet.RepositoryFactory** NuGet package provides a streamlined way to manage data access in .NET applications, leveraging best practices for transaction management and parallel operations. With support for various service lifetimes, you can now tailor the package to suit your application's specific needs. By following this guide, you can easily integrate this package into your projects and take advantage of its robust features.\n\nFor more details or support, please refer to the package documentation or reach out to the community for assistance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsx752%2Fsampledotnet.repositoryfactory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsx752%2Fsampledotnet.repositoryfactory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsx752%2Fsampledotnet.repositoryfactory/lists"}