{"id":36464448,"url":"https://github.com/stoveproject/Stove","last_synced_at":"2026-01-18T17:00:45.359Z","repository":{"id":60773402,"uuid":"77679700","full_name":"stoveproject/Stove","owner":"stoveproject","description":"Domain Driven Design oriented application framework, meets CRUD needs","archived":true,"fork":false,"pushed_at":"2018-12-11T21:05:54.000Z","size":16170,"stargazers_count":165,"open_issues_count":1,"forks_count":37,"subscribers_count":24,"default_branch":"dev","last_synced_at":"2026-01-14T05:09:54.810Z","etag":null,"topics":["cqrs","dapper","dbcontext","ddd","domain-driven-design","entity-framework","framework","hangfire","nhibernate","nlog","rabbitmq","ravendb","redis","stove","transaction"],"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/stoveproject.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":null,"support":null}},"created_at":"2016-12-30T10:32:05.000Z","updated_at":"2025-08-21T21:04:42.000Z","dependencies_parsed_at":"2022-10-04T15:32:53.763Z","dependency_job_id":null,"html_url":"https://github.com/stoveproject/Stove","commit_stats":null,"previous_names":["osoykan/stove"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/stoveproject/Stove","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoveproject%2FStove","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoveproject%2FStove/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoveproject%2FStove/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoveproject%2FStove/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stoveproject","download_url":"https://codeload.github.com/stoveproject/Stove/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoveproject%2FStove/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28543492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T14:59:57.589Z","status":"ssl_error","status_checked_at":"2026-01-18T14:59:46.540Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cqrs","dapper","dbcontext","ddd","domain-driven-design","entity-framework","framework","hangfire","nhibernate","nlog","rabbitmq","ravendb","redis","stove","transaction"],"created_at":"2026-01-12T00:00:48.965Z","updated_at":"2026-01-18T17:00:45.308Z","avatar_url":"https://github.com/stoveproject.png","language":"C#","funding_links":[],"categories":["Supported Packages"],"sub_categories":[],"readme":"#   Stove [![Build status](https://ci.appveyor.com/api/projects/status/wv4049ey7666vrq4?svg=true)](https://ci.appveyor.com/project/osoykan/stove-jo52k) \u003cimg src=\"https://raw.githubusercontent.com/osoykan/Stove/master/stove.png\" alt=\"alt text\" width=\"100\" height=\"100\"\u003e  \n\n\n|Package|Status|\n|:------|:-----:|\n|Stove|[![NuGet version](https://badge.fury.io/nu/Stove.svg)](https://badge.fury.io/nu/Stove)|\n|Stove.Entityframework|[![NuGet version](https://badge.fury.io/nu/Stove.EntityFramework.svg)](https://badge.fury.io/nu/Stove.EntityFramework)|\n|Stove.EntityframeworkCore|[![NuGet version](https://badge.fury.io/nu/Stove.EntityFrameworkCore.svg)](https://badge.fury.io/nu/Stove.EntityFrameworkCore)|\n|Stove.Hangfire|[![NuGet version](https://badge.fury.io/nu/Stove.Hangfire.svg)](https://badge.fury.io/nu/Stove.Hangfire)|\n|Stove.NLog|[![NuGet version](https://badge.fury.io/nu/Stove.NLog.svg)](https://badge.fury.io/nu/Stove.NLog)|\n|Stove.Serilog|[![NuGet version](https://badge.fury.io/nu/Stove.Serilog.svg)](https://badge.fury.io/nu/Stove.Serilog)|\n|Stove.Mapster|[![NuGet version](https://badge.fury.io/nu/Stove.Mapster.svg)](https://badge.fury.io/nu/Stove.Mapster)|\n|Stove.Redis|[![NuGet version](https://badge.fury.io/nu/Stove.Redis.svg)](https://badge.fury.io/nu/Stove.Redis)|\n|Stove.Dapper|[![NuGet version](https://badge.fury.io/nu/Stove.Dapper.svg)](https://badge.fury.io/nu/Stove.Dapper)|\n|Stove.RabbitMQ|[![NuGet version](https://badge.fury.io/nu/Stove.RabbitMQ.svg)](https://badge.fury.io/nu/Stove.RabbitMQ)|\n|Stove.NHibernate|[![NuGet version](https://badge.fury.io/nu/Stove.NHibernate.svg)](https://badge.fury.io/nu/Stove.NHibernate)|\n|Stove.RavenDB|[![NuGet version](https://badge.fury.io/nu/Stove.RavenDB.svg)](https://badge.fury.io/nu/Stove.RavenDB)|\n|Stove.Couchbase|[![NuGet version](https://badge.fury.io/nu/Stove.Couchbase.svg)](https://badge.fury.io/nu/Stove.Couchbase)|\n\nStove is an application framework that wraps and abstracts your needs for easy use. Built with strongly adopted dependency injection principles.\n\n## IoC\n* Autofac\n* Conventional Registration Mechanism with [Autofac.Extras.IocManager](https://github.com/osoykan/Autofac.Extras.IocManager) \n\n## Use-Case \u0026 Transaction approach\n* AsyncLocal Unit Of Work pattern\n\n## Adopted principles\n* Domain Driven Design\n* Persistence agnosticism with **IRepository\u0026lt;T\u0026gt;**\n* EventBus for DDD use cases\n\n## Persistence Support\n* EntityFramework\n* EntityFramework Core\n* NHibernate\n\n## Transactional structure\n|Tool|Supports Multiple Database/Session Control inside one UOW|\n|:------|:-----:|\n|EntityFramework| :white_check_mark: |\n|EntityFrameworkCore| :white_check_mark: |\n|NHibernate| :white_check_mark: |\n|Dapper| :white_check_mark: |\n\n### Notes\n\n* To work with Dapper, you must use EF \u0026 EF Core or NHibernate as primary ORM choice. Dapper shares their transactions to execute its sqls inside of one **Unit Of Work** scope.\n* **Dapper-EntityFramework**, **Dapper-NHibernate** or **Dapper-EntityFrameworkCore** works under same transaction and unit of work scope, if any exception appears in domain **whole transaction will be rollback**, including Dapper's insert/deletes or EF's or NH's.\n* Stove.Dapper supports **Dynamic Filters** to filter automatically and default ISoftDelete or other user defined filters.\n\n* NHibernate **supports multiple database** in one UOW scope.\n\n### Nhibernate Multiple Database\n\nLet's assume that we have two entities which are inherited from **Entity\u0026lt;int\u0026gt;**. If we want to work with multiple database with NHibernate we have to tell to Stove that which entities belong to which database or session. To achive that Stove has to know your database distinction. Basically `StoveSessionContext` does that.\n\n#### StoveSessionContext\n\n```csharp\npublic class PrimaryStoveSessionContext : StoveSessionContext\n{\n    public IStoveSessionSet\u003cProduct\u003e Products { get; set; }\n}\n```\n\n```csharp\npublic class SecondaryStoveSessionContext : StoveSessionContext\n{\n    public IStoveSessionSet\u003cCategory\u003e Categories { get; set; }\n}\n```\n\nRegistration:\n\n```csharp\nbuilder\n    .UseStoveNHibernate(nhConfiguration =\u003e\n    {\n        nhConfiguration.AddFluentConfigurationFor\u003cPrimaryStoveSessionContext\u003e(() =\u003e\n        {\n            return Fluently.Configure()\n                           .Database(SQLiteConfiguration.Standard.InMemory())\n                           .Mappings(m =\u003e m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))\n                           .ExposeConfiguration(cfg =\u003e new SchemaExport(cfg).Execute(true, true, false, _connection, Console.Out));\n        });\n\n        nhConfiguration.AddFluentConfigurationFor\u003cSecondaryStoveSessionContext\u003e(() =\u003e\n        {\n            return Fluently.Configure()\n                           .Database(SQLiteConfiguration.Standard.InMemory())\n                           .Mappings(m =\u003e m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))\n                           .ExposeConfiguration(cfg =\u003e new SchemaExport(cfg).Execute(true, true, false, _connection, Console.Out));\n        });\n\n        return nhConfiguration;\n    })\n```\n\nAfter this definition, we have to define which SessionContext uses which connection string for connect to database and creating session factory.\n```csharp\n [DependsOn(\n     typeof(StoveNHibernateBootstrapper)\n )]\n public class StoveNHibernateTestBootstrapper : StoveBootstrapper\n {\n     public override void PreStart()\n     {\n         StoveConfiguration.DefaultNameOrConnectionString = \"data source=:memory:\";\n         StoveConfiguration.TypedConnectionStrings.Add(typeof(PrimaryStoveSessionContext),StoveConfiguration.DefaultNameOrConnectionString);\n         StoveConfiguration.TypedConnectionStrings.Add(typeof(SecondaryStoveSessionContext),StoveConfiguration.DefaultNameOrConnectionString);\n\n         DapperExtensions.DapperExtensions.SqlDialect = new SqliteDialect();\n         DapperExtensions.DapperExtensions.SetMappingAssemblies(new List\u003cAssembly\u003e { Assembly.GetExecutingAssembly() });\n     }\n }\n```\nAs you see connection strings are same but they are inside of different **StoveSessionContexts**. If these entities are inside of same database but you want to treat as different bounded contexts to them, you can choose this kind of approach for your sessions. Otherwise entities can sit together in one **SessionContext**.\n\nUsage is always same and persistence agnostic:\n```csharp\n using (IUnitOfWorkCompleteHandle uow = The\u003cIUnitOfWorkManager\u003e().Begin())\n {\n     The\u003cIDapperRepository\u003cProduct\u003e\u003e().GetAll().Count().ShouldBe(1);\n     The\u003cIRepository\u003cProduct\u003e\u003e().GetAll().Count().ShouldBe(1);\n\n     uow.Complete();\n }\n```\n\n## Document Databases\n* RavenDB -\u003e **IRepository\u0026lt;T\u0026gt;**\n* Couchbase -\u003e **IRepository\u0026lt;T\u0026gt;**\n\n## Queue Mechanism\n\n* RabbitMQ support\n\n## Background Jobs\n\n* HangFire support\n\n## Caching\n\n* Redis support\n\n## Others\n\n* A lot of extensions\n* Strictly **SOLID**\n\n## Composition Root\n```csharp\nIRootResolver resolver = IocBuilder.New\n                                   .UseAutofacContainerBuilder()\n                                   .UseStove\u003cStoveDemoBootstrapper\u003e(autoUnitOfWorkInterceptionEnabled: true)\n                                   .UseStoveEntityFramework()\n                                   .UseStoveDapper()\n                                   .UseStoveMapster()\n                                   .UseStoveDefaultEventBus()\n                                   .UseStoveDbContextEfTransactionStrategy()\n                                   .UseStoveTypedConnectionStringResolver()\n                                   .UseStoveNLog()\n                                   .UseStoveBackgroundJobs()\n                                   .UseStoveRedisCaching()\n                                   .UseStoveRabbitMQ(configuration =\u003e\n                                   {\n                                       configuration.HostAddress = \"rabbitmq://localhost/\";\n                                       configuration.Username = \"admin\";\n                                       configuration.Password = \"admin\";\n                                       configuration.QueueName = \"Default\";\n                                       return configuration;\n                                   })\n                                   .UseStoveHangfire(configuration =\u003e\n                                   {\n                                       configuration.GlobalConfiguration\n                                                    .UseSqlServerStorage(\"Default\")\n                                                    .UseNLogLogProvider();\n                                       return configuration;\n                                   })\n                                   .RegisterServices(r =\u003e r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()))\n                                   .CreateResolver();\n\nvar someDomainService = resolver.Resolve\u003cSomeDomainService\u003e();\nsomeDomainService.DoSomeStuff();\n \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstoveproject%2FStove","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstoveproject%2FStove","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstoveproject%2FStove/lists"}