Spring.NET: the Java Spring model carried over to C# and .NET
Spring Framework for .NET
At a glance
- What is it?
- Spring.NET is a C# port of the Java Spring Framework, split into NuGet packages for dependency injection, AOP, transaction management, ASP.NET and NHibernate. It grew out of the ASP.NET and .NET Framework era, and its component set still reflects that, which is both its selling point and its constraint.
- Who is it for?
- Adopt Spring.NET when you are maintaining a .NET Framework or .NET Standard codebase that already speaks the Spring configuration model and you want declarative transactions, AOP and DI without rewriting them. Do not adopt it for a greenfield ASP.NET Core service, since the packages listed cover ASP.NET, MVC5, WCF and .NET Remoting rather than the modern .NET stack.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Spring.NET actually is: a port, with the same vocabulary
The README is direct about the project's origins. Spring.NET is a port of the Java based Spring Framework, which in turn derives from code published in "Expert One-on-One J2EE Design and Development" by Rod Johnson in 2002. That lineage explains almost every design decision you will meet in the code.
The container model is the Java one. You define beans, wire them with XML configuration, and let the container assemble the object graph, with dependency injection and AOP applied through the same concepts Java developers use. The README lists a full featured Inversion of Control container, an Aspect Oriented Programming framework, an Expression Language for lightweight scripting, and a UI-agnostic validation framework as the four foundation pieces.
Around those sit the integration layers: ASP.NET with dependency injection for pages and user controls, ASP.NET MVC and ASP.NET WebAPI, a declarative transaction management abstraction, an ADO.NET framework with DAO support classes, and a set of provider integrations for NHibernate, WCF, Quartz, MSMQ, NMS, TIBCO EMS and NVelocity.
The appeal is familiarity for anyone who has used Spring in Java. The catch, which the rest of this article returns to, is that the integration targets are all of a particular vintage: System.Web-era ASP.NET, MVC5, WCF, .NET Remoting and NHibernate 5.
The NuGet package split and the dependency chain underneath it
Spring.NET is not distributed as one assembly. The README documents the contents of the bin directory as a set of distinct DLLs, each published to NuGet, and the dependency list forms a small graph.
Spring.Core carries the inversion of control container and the collection classes, and depends only on Common.Logging. Spring.Aop adds the Aspect Oriented Programming framework on top of Spring.Core and Common.Logging. Spring.Data sits above those two and provides the transaction and ADO.NET framework, which is what the README calls the transaction and ADO.NET framework with DAO support classes and integration with the declarative transaction management.
Above that, the packages divide by host technology. Spring.Web is the ASP.NET based web application framework and depends on Spring.Core and Spring.Aop. Spring.Web.Extensions adds ASP.NET AJAX integration and pulls in System.Web.Extensions. Spring.Web.Mvc5 covers ASP.NET MVC5 and WebAPI integration and depends on Spring.Core and Spring.Web. Spring.Services covers web services, remoting and enterprise component based services. Spring.Data.NHibernate5 integrates NHibernate 5.x with the declarative transaction management.
The testing packages follow the same pattern. Spring.Testing.NUnit depends on Spring.Core, Spring.Data and NUnit, and Spring.Testing.Microsoft covers the MSTest side, providing dependency injection of test cases, container loading and caching, and the data access and transaction features that integration tests need.
That structure lets you take only the layer you want. A console application that wants declarative transactions installs Spring.Core, Spring.Aop and Spring.Data and stops there.
The long tail of provider integrations
Beyond the core packages, the README lists integrations that are mostly thin wrappers around message queues, schedulers and template engines, each with the same shape: helper classes for sending and receiving, plus a hook into Spring's transaction management.
Quartz integration configures Quartz jobs through dependency injection and uses Spring's transactional support to persist job details, so the scheduler and the database stay in step with the same transaction boundary as the rest of the application. MSMQ integration simplifies sending and receiving and integrates with the transaction management features. NMS integration and TIBCO EMS integration do the same for the NMS messaging API and for TIBCO EMS respectively. WCF integration provides dependency injection and applies AOP advice to WCF services.
NVelocity integration is about configuring NVelocity rather than messaging. Portable Service Abstractions take plain .NET objects and export them over .NET Remoting, a Web Service or a .NET serviced component, then generate client side proxies from an endpoint URL and a service interface.
Taken together these tell you what kind of codebase Spring.NET was designed for: enterprise .NET Framework applications in the 2010s style, where an order enters through a queue, a scheduled job processes it, the result goes out over a remoting channel, and every hop needs the same transaction semantics. ASP.NET AJAX integration closes the loop by exposing a plain object, with dependency injection and AOP already applied, to JavaScript.
The question worth asking now is how much of that stack still exists in the application you have in mind.
Getting the packages into a project
The README does not document an installation command. What it does document is the NuGet package names, each with a badge linking to its NuGet page: Spring.Core, Spring.Aop, Spring.Data, Spring.Data.NHibernate5, Spring.Services, Spring.Web, Spring.Web.Extensions, Spring.Web.Mvc5, Spring.Testing.NUnit and Spring.Testing.Microsoft.
Two transitive details deserve attention before you start. Common.Logging appears as a dependency of both Spring.Core and Spring.Aop, so it will be pulled in whether or not your application uses it directly. The NHibernate package depends on NHibernate itself, so using Spring.Data.NHibernate5 also fixes an NHibernate major version for you, and the package is named for NHibernate 5.x specifically. The README also gives approximate download sizes, from roughly 8 KB for Spring.Web.Extensions and Spring.Web.Mvc5 up to about 765 KB for Spring.Core, which is a reasonable sanity check that you are pulling the assembly you intended.
On target frameworks, the README states that Spring.NET 3.0.0 supports .NET 4.6.2 and .NET Standard 2.0 and later. Note the version in that sentence. The most recent release listed is v3.1.0, tagged Spring.NET 3.1.0 GA on 2026-08-09, and the framework support line in the README still names 3.0.0, so the documentation is one minor version behind the packages. Confirm the supported targets against the package you actually install rather than trusting that line.
Full documentation, installation instructions and examples live on the project website at www.springframework.net, and the doc directory in the repository holds reference documentation, MSDN-style API help and the Spring.NET xsd.
Building the framework and the SQL Server service behind the test runs
The repository is laid out the way a long-lived .NET Framework project tends to be. src holds the C# source for the framework, test holds the test suite, bin holds the distribution DLLs, lib/Net holds shared third-party libraries needed for the build, doc holds the reference documentation and the Spring.NET xsd, examples holds sample applications, and build-support and dev-support hold NAnt helpers and developer tooling such as VS.NET solution templates.
Building is driven by a family of scripts rather than a single cross-platform entry point: build.cmd, build.ps1, build.sh, Build-ci.cmd, package-nuget-only.cmd and powershell-invoker.cmd sit at the root, alongside docker-compose.yml, docker-compose-ci.yml, appveyor.yml.old and a set of S3 nightly upload scripts. The presence of s3-nightly-upload.ps1 and s3-nightly-delete-old-files.ps1 indicates that nightly builds are published to S3 in addition to the tagged NuGet releases.
The compose file provisions SQL Server for the integration tests:
version: '2'
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04
environment:
- MSSQL_PID=Express
- ACCEPT_EULA=Y
- SA_PASSWORD=MyPassword!
ports:
- 1433:1433That is the whole service definition. The Express edition image with the sa password supplied through the environment is a test convenience, not a production configuration, and the image tag pins a 2019 cumulative update on an Ubuntu 16.04 base. If you are setting up the test environment yourself, the port mapping on 1433 is the standard SQL Server instance port and the password here is a placeholder that you should change before running anything on a shared machine.
The constraint that shapes every decision: the target stack
Look at the component names again and the shape of the project becomes clear. Spring.Web and Spring.Web.Extensions target ASP.NET and System.Web.Extensions. Spring.Web.Mvc5 targets MVC5 and WebAPI. Spring.Services is built on .NET Remoting, Web Services and serviced components. The NHibernate integration is pinned to version 5.
None of these is ASP.NET Core, and the README never mentions it. That is not an omission so much as a boundary: the ecosystem of ASP.NET Framework, WCF, .NET Remoting and NHibernate 5 is the one this framework integrates with. A team starting a new service on current .NET will find its dependency injection, its logging, its transactions and its HTTP layer already in the platform, and will find that the Spring.NET equivalents for those layers do not target it.
There is a second, quieter limitation. Most of the value in a port like this comes from configuration consistency, and the XML-driven model is the source of that consistency. XML is verbose, and it is a format that a lot of newer tooling treats as legacy. A codebase that has adopted source-generated configuration or a code-based container style will find the XML file another dialect to maintain, and the Spring.NET XSD shipped in doc is a reminder that the schema has to be kept in step with the code.
A final note on scope: the README's own feature list is a 2010s enterprise application feature set. There is nothing here about message streaming with Kafka, gRPC contracts, or cloud-native configuration, and reading the list as a gap analysis for a modern architecture is more useful than reading it as a feature comparison with Java Spring.
Spring.NET against the platform's own transaction and service APIs
The honest comparison is not with another Spring port. It is with using the .NET transaction APIs directly, and with using the platform's remoting and messaging options without an abstraction on top.
The difference the declarative transaction management abstraction makes is uniformity. The README describes it as declarative transaction management via use of common XML configuration and attributes across different transaction APIs, and the DAO support classes in Spring.Data tie that into ADO.NET. Without it, each store you touch, ADO.NET here, NHibernate there, a WCF service call elsewhere, each has its own way of expressing a transaction boundary and its own enlistment rules. With it, the boundary is declared once in configuration and applies across the participants, and the Quartz, MSMQ and NMS integrations exist so that a job schedule and a message send can sit inside that same boundary.
The platform-native alternative is more direct and less machinery. ADO.NET has its own transaction classes, NHibernate has its own transaction API, and WCF has its own transaction attributes. If your application touches exactly one of those, the Spring abstraction adds a layer of configuration and an extra assembly to read through, and the value it delivers is thin.
The service abstraction is the other place where the comparison bites. Portable Service Abstractions let you export a plain .NET object over .NET Remoting, a Web Service or a serviced component and get client side proxies generated from the endpoint URL and the service interface. That is a genuine convenience for a distributed .NET Framework application, and it is also the part of the framework most tied to technologies the wider industry has moved away from. Deciding between them comes down to whether the code you are extending was written for that era of .NET. If it was, Spring.NET will feel familiar; if it was not, the framework costs more to learn than it saves.
Release cadence and what the Apache 2.0 licence means for adoption
Development on the repository is current. The last push was on 2026-10-15, and the tagged releases tell their own story: v3.1.0, tagged Spring.NET 3.1.0 GA, on 2026-08-09, v3.0.3 on 2025-07-28, and v3.0.2 on 2023-07-06. Three years separate the 3.0.2 and 3.0.3 tags, then a gap of a year to the 3.1.0 GA. So the project is under active development with tagged releases that arrive infrequently rather than on a predictable schedule.
That gap between commit activity and release tags matters for adoption. Nightly packages appear to be uploaded to S3, which gives you a way to consume recent builds, but the published NuGet versions are the ones you can rely on for a production dependency graph.
The licence is the Apache Software License, with the repository shipping the terms in license.txt. As a matter of reading the text rather than legal advice, the Apache 2.0 grant is permissive, it allows use inside proprietary and commercial products, and its obligations are the usual ones: keep the copyright notice and the licence text with the copies you distribute, and note the modifications you make. For organisations with an Apache 2.0 policy already, there is nothing here to reconcile.
One last piece of administrative detail. The repository root contains BreakingChanges.txt and changelog.txt, and a spring configuration XSD in the doc directory. For a framework upgrade, those two files are where the work is: read the breaking changes for your version before you touch an import statement.
Editorial conclusion
Adopt Spring.NET when you are maintaining a .NET Framework or .NET Standard codebase that already speaks the Spring configuration model and you want declarative transactions, AOP and DI without rewriting them. Do not adopt it for a greenfield ASP.NET Core service, since the packages listed cover ASP.NET, MVC5, WCF and .NET Remoting rather than the modern .NET stack. Verify first which target framework your version of the packages supports, because the README still describes .NET 4.6.2 and .NET Standard 2.0 and later, and check the dependency list of each Spring package before you commit to one.
Frequently asked questions
How do I install Spring.NET in a .NET project?
The README documents the packages rather than an installation command: Spring.Core, Spring.Aop, Spring.Data, Spring.Web, Spring.Web.Mvc5, Spring.Data.NHibernate5, Spring.Services and the testing packages are each published on NuGet. Full installation instructions are on the project website at www.springframework.net.
Which .NET versions does Spring.NET support?
The README states that Spring.NET 3.0.0 supports .NET 4.6.2 and .NET Standard 2.0 and later. That line still names 3.0.0 while the latest release listed is Spring.NET 3.1.0 GA from 2026-08-09, so check the target frameworks on the package you install.
Does Spring.NET work with ASP.NET Core?
The README does not mention ASP.NET Core. The listed packages cover ASP.NET, ASP.NET MVC5 and WebAPI, WCF, .NET Remoting and NHibernate 5, so the framework targets the ASP.NET Framework era of .NET rather than the current stack.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/spring-projects-spring-net)Was this useful?