The principle is to move the complexity to the correct place, allowing to write stupid simple business logic.
Around these concepts, some libraries were created to address the accidental complexity, implementing the infrastructure of these concepts in real life. These libraries help in developing service applications. It implements most common non-functional requirements using abstractions to permit that you write only one agnostic service layer.
A few years ago, I've started using Spring.NET as a principal IoC Container. Spring.NET is a most important implementation about the inversion of control and dependency injection on .NET. Providing an XML declarative way to configure factory, dependency, and control flow behaviors. Spring.NET is helpful to connect dots in a long way of disconnected services and technologies. After .NET Core and .NET Standard be launched, I've tried to update the original project to compatibility with .NET Standard, but original Spring.NET has many, useless for me, projects. Instead, the Oragon base architecture, written in 2006, and rewrote sometimes later, need only of two projects: Spring.Core and Spring.Aop. That I've trying to show that port is simples, but I had no result with the original community. And so I forked this project creating Spring.Summer (a joke) and later renaming to Oragon.Spring. Oragon.Spring has only 2 projects on requirements. and we need only 2 I've decided port this project to .NET Standard and I've created Oragon.Spring a direct fork of Spring.NET implemented to be compatible with .NET Standard 2.
You don't need handle exception if it doesn't represent a flow change on your business code. If your unique requirements to implement a try-catch is a logging, rollback the database transaction, or switch the exception to another generic, you don't need to write any try-catch on the service layer.
Provide an abstraction to write complex logs, and delivery a base implementation to publish your logs on RabbitMQ. You can implement your own output, like File, Other MQ implementation or another strategy. Complex logs as defined as a log with custom properties and values. That provides contextual information about execution contexts. You can add what you need to explain better your log, like variables, parameters, and environment variables to help on troubleshooting.
Connected Service provide abstractions to connect technologies like AMQP, HTTP, SOAP and others technologies on your agnostic services. It's helpful to delivery most common technology scenarios with the same codebase. A unique single method of your service can be exposed as: An HTTP route. An AMQP Queue Worker. A Stream Processor. A normal Method used by dependents.
All in one, without changes, without knowing what technology is used on current execution, allowing to connect a new technology on the same old codebase, without a rebuild, only adding configuration statements.
Complex Contexts Is helpful for implement crosscutting concerns like transactions, connections and whatever you want to pass to call stack in deeply without dirty your domain/model/business logic layer or whatever you called as your Business Code with parameters that explain specific technologies and building a non-agnostic domain. We have an extensible NHibernate infrastructure with FluentNHibernate to provide a simple way delivery a configurable, cross-platform, cross-database Unit of Work.