Skip to content

Instantly share code, notes, and snippets.

@Lakritzator
Last active August 21, 2024 07:13
Show Gist options
  • Save Lakritzator/d395f76dafbd51b03533af968982ff92 to your computer and use it in GitHub Desktop.
Save Lakritzator/d395f76dafbd51b03533af968982ff92 to your computer and use it in GitHub Desktop.
A comparison between Javas Spring-Boot and the Generic Host of dotnet core

This is work in progress

I read about the .NET Generic Host for the first time in a Tweet of David Fowler. And I was hooked by the idea, it was just what I was looking for.

I like modules making things small but fit together like pieces of a puzzle, if possible being able to reuse them. I started refactoring Greenshot over a year ago, and was making modules out of the spaghetti code that it was. Trying to extract the modules into their own nuget packages, making them more generic and testable. I glued them together with some code I wrote, which is availble in Dapplo.Addons, but I knew that this was just a journey, until I found something that is a better with more potential.

I found the following description: The purpose of Generic Host is to enable a wider array of host scenarios. Messaging, background tasks, and other non-HTTP workloads based on Generic Host benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging.

I wasn't directly sure about the scenarios one would use it for, but than after seeing a couple of examples I changed my view. When thinking the implementation details away, and trying just to see the functionality, I could see similarities with Spring Boot, which is one of my favorite Java projects. The site for Spring-Boot says: Spring Boot makes it easy to create stand-alone, production-grade Applications that you can "just run".

Spring-Boot, in my words, makes it possible to write an Enterprise grade Java application which uses plugable services & functionality for which normally one would use a J2EE application server like JBoss, Tomcat etc.

Don't get me wrong, the implementation is VERY different, but it should be possible to produce similar products. This article is about how we can use the generic host to make a modular application, similar to using Spring-Boot.

I will try to describe the similarities and some of the the gaps, between both solutions and hopefully come up with some solutions for those gaps.

Let's see how the two implementations compare on a functional level, only covering a subset of the possibilities:

Spring projects Description .NET implementation
Spring Boot Easy to create stand-alone, production-grade Applications that you can "just run". The HostBuilder for the "generic host"
Spring Framework Provides a comprehensive programming and configuration model for modern Java-based enterprise applications. Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP. Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient. Data Access: transactions, DAO support, JDBC, ORM, Marshalling XML. Spring MVC and Spring WebFlux web frameworks. Integration: remoting, JMS, JCA, JMX, email, tasks, scheduling, cache. Languages: Kotlin, Groovy, dynamic languages. Build in IoC, Loggin etc of the "generic host"
Spring Data Provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store. The list of Spring-Data projects is substantial:
Spring Data JDBC
Spring Data JDBC Extensions
Spring Data JPA
Spring Data LDAP
Spring Data MongoDB
Spring Data Redis
Spring Data R2DBC
Spring Data REST
Spring Data for Apache Cassandra
Spring Data for Apache Geode
Spring Data for Apache Solr
Spring Data for Pivotal GemFire
Spring Data Couchbase
Spring Data Elasticsearch
Spring Data Envers
Spring Data Neo4J
Spring for Apache Hadoop
Entity Framework Core
Spring Cloud Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). The sub-projects for Spring-Cloud are
Spring Cloud Stream
Spring Cloud Azure
Spring Cloud for Amazon Web Services
Spring Cloud Bus
Spring Cloud CLI
Spring Cloud for Cloud Foundry
Spring Cloud - Cloud Foundry Service Broker
Spring Cloud Cluster
Spring Cloud Commons
Spring Cloud Config
Spring Cloud Connectors
Spring Cloud Consul
Spring Cloud Contract
Spring Cloud Function
Spring Cloud Gateway
Spring Cloud GCP
Spring Cloud Netflix
Spring Cloud Open Service Broker
Spring Cloud Pipelines
Spring Cloud Security
Spring Cloud Sleuth
Spring Cloud Stream App Starters
Spring Cloud Task
Spring Cloud Task App Starters
Spring Cloud Vault
Spring Cloud Zookeeper
Spring Cloud App Broker
Spring Cloud Kubernetes
Spring Cloud OpenFeign
Spring Cloud Data Flow
Spring Cloud Netflix contains Eureka, which is covered by [Steeltoe's Service Discover](https://steeltoe.io/docs/steeltoe-discovery/ and Circuit Breaker (Hystrix) which is similar to Polly)
Spring Cloud Data Flow Microservice based Streaming and Batch data processing for Cloud Foundry and Kubernetes.
Spring-Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. ASP.NET core security
Spring Session Provides an API and implementations for managing a user’s session information.
Spring Integration Extends the Spring programming model to support the well-known Enterprise Integration Patterns.
Spring HATEOAS Spring HATEOAS provides some APIs to ease creating REST representations that follow the HATEOAS principle when working with Spring and especially Spring MVC.
Spring REST Docs Helps you to document RESTful services. HTTP Repl
Spring Batch A lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operations of enterprise systems.
Spring AMQP The Spring AMQP project applies core Spring concepts to the development of AMQP-based messaging solutions. RabbitMQ dotnet
Spring for Android is an extension of the Spring Framework that aims to simplify the development of native Android applications. Xamarin
Spring Cloud Skipper Skipper is a tool that allows you to discover Spring Boot applications and manage their lifecycle on multiple Cloud Platforms.
Spring CredHub Spring CredHub provides client-side support for storing, retrieving, and deleting credentials from a CredHub server running in a Cloud Foundry platform. Steeltoe
Spring Flo Is a JavaScript library that offers a basic embeddable HTML5 visual builder for pipelines and simple graphs. This library is used as the basis of the stream builder in Spring Cloud Data Flow.
Spring for Apache Kafka applies core Spring concepts to the development of Kafka-based messaging solutions. Confluent Kafka dotnet
Spring LDAP Is a library to simplify LDAP programming in Java, built on the same principles as Spring Jdbc.
Spring Mobile is an extension to Spring MVC that aims to simplify the development of mobile web applications. Xamarin
Spring Roo A next-generation rapid application development tool for Java developers. With Roo you can easily build full Java applications in minutes.
Spring Shell provides an interactive shell that allows you to plugin your own custom commands using a Spring based programming model.
Spring Statemachine is a framework for application developers to use state machine concepts with Spring applications. Stateless
Spring Test HtmlUnit Provides integration between Spring MVC Test Framework and HtmlUnit.
Spring Vault provides familiar Spring abstractions and client-side support for accessing, storing and revoking secrets.
Spring Web Flow allows implementing the "flows" of a web application.
Spring Web Services is a product of the Spring community focused on creating document-driven Web services.

I've extracted some of the Spring-Framework core functionality, to get into more details:

Functionality Spring (-Boot) Generic Host
Dependency Injection Spring-Framework Microsoft.Extensions.DependencyInjection Docs: DI
web framework Spring-MVC ASP.NET Core in the Microsoft.AspNetCore namespace, e.g. MVC
Configuration Spring-Cloud-Config configuration ( Microsoft.Extensions.Configuration and Microsoft.Extensions.Options
Security Spring-Security ASP.NET core security
Composition / Add-on (Component scanning](https://springframework.guru/spring-component-scan/) ??? (see further)

Here are the Microsoft.Extensions I needed, and I created:

  • Plugin or composition support, in Spring-Boot this is called component scan.
  • WPF / WindowsForms lifetime support
  • Caliburn.Micro bootstrapper

I'm first writing a prototype: With the Spring-Framework it's very common to have component scanning, this detects additional components and will wire these into your application. For the generic host I have not yet found such a thing, this is a functionality I really need for Greenshot! I will try to write a prototype for this in my GenericHostPlayground (Current status - Prototype is working, look at the repo issues for currently know issues)

A list of currently available packages on nuget can be found here which already were 465 at the time of writing this. Unfortunately these are currently mainly logging and dependency injection adaptors.

Here are a few blog posts I found:

@Lakritzator
Copy link
Author

Lakritzator commented Jul 4, 2019

I'll need to add the functionality of https://steeltoe.io/

Probably it makes sense to get a table describing "Spring" solutions, and what dotnet solutions covers a similar functionality.

Spring Cloud Netflix Eureka

Spring Data / JPA / Hibernate

@lsiu
Copy link

lsiu commented Jan 19, 2021

The Composition / Add-on is spot on. It is the strong point of Spring Boot, which brings the "Ruby on Rails + gem"-esque to the JVM world. However, I think calling it "component scanning" is doing it a little disservice, Spring Boot calls it Auto Configuration.

For those not familar with this concept, I just want to illustrate it will this example:

  1. You started your web project with Spring Initializer and it is just some REST endpoint for your business domain.
  2. You need monitoring so you just add spring-boot-starter-actuator into your project dependency, and volia, you have your health check endpoint up in at /actuator/health. I want to emphasize it is literally just adding the dependency will give you this functionality. There is zero code you need to copy and paste from other project to enable this function.
  3. Next you need a database and you just add spring-boot-starter-data-jpa to your project dependency and the jdbc driver of you favorite database.
  4. The best part now is, the /actuator/heath endpoint created in step 2., before you added the database to your project, now displays the status of the database connection in your runtime and you wrote zero code.

This is the power of auto configuration and convention over configuration which Spring Boot picked up from Ruby on Rails.

Some people think this is too much magic, especially people coming from the "old Microsoft world", where many libraries are close source. My argument is, this magic is also just code, it is open source, and with the modern IDE intergation, artifacts repositories and the maturity of the toolchain, you can read this magic code quite readily from your favorite IDE by just clicking into the code.

With the general trend of breaking down monolith SaaS application into smaller-manageable-deployable units, (yes, I am avoiding the word microservice), now imagine what it brings to you when you start a new service. For example, you need SSO and RBAC security to your new service, you just include the latest dependency into your project and it just works. It auto-magically connects to your company's SSO, I&AM solution.

This concept just brings a whole new layer of abstraction to software development. You can now glue pieces together, with a lot less glue (code). So when people are still arguing how Java lacks the optional/nullable syntax that C# has, or how the Java Stream API is so verbose is complete missing the point.

Lastly, you are correct in bringing steeltoe to the picture, which brings this capability to C#. However, with these abstractions, there is network effect in play, where the participants of ecosystem makes existing ecosystem rich and powerful. I am afraid Steeltoe/C# has missed the boat and is falling to the wayside, just like Microsoft's past attempt to make Windows Server still relevant in the large scale SaaS development.

Having said the above, C# has its place. For smaller shops, with Microsoft history of UI, wizard centric, IT administration and application development, the ecosystem is ideal for companies that software is not their core-competency, and they need simple software in-house software to just work. There are still a lot of software out there that don't have a SaaS equivalent, and Microsoft ecosystem excel in this space, and this space is huge too.

@fkromer
Copy link

fkromer commented Mar 23, 2021

Great gist, thanks a lot! I'm gooing to reference it into one of my future medium posts for sure!

@hananiel
Copy link

Checkout https://docs.steeltoe.io/api/v3/messaging/rabbitmq-intro.html for Spring-Amqp (much closer abstractions to Spring-amqp than RabbitMq Dotnet- it is infact built on top of ... ) and https://docs.steeltoe.io/api/v3/stream/ for (spring-cloud-stream) and support for SCDF.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment