# Introduction

# What is Dovetail?

![Dovetail overview diagram](https://dummyimage.com/1200x560/0b1220/f8fafc.png&text=Dovetail+Overview+Architecture)

The goal of Dovetail is to be a simple way to bridge the gap between Configuration driven development and Dovetail driven development.
In an ASP.NET Core application it is "pay-for-play" in that you must register all your configurations, services, etc. This is great but it
also forces you into cases where if you forget to call an extension method nothing lights up like you expected. Another draw back of using
extension methods is that any dependencies you need, to configure services for example, must be included in the method call.

One thing to keep in mind is that ASP.NET Core just got rid of the [double container](https://github.com/aspnet/Announcements/issues/353)
problem, we are not introducing a second container, instead we just implement `IServiceProvider` using the same [dictionary that is provided
by `IHostBuilder.Properties`](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostbuilder.properties). Any services
that you inject into your joints must exist inside of this dictionary, or be optional.

At a high level Dovetail solves this problem in a very similar way to something like [Autofac Modules](https://autofaccn.readthedocs.io/en/latest/configuration/modules.html)
or other similar assembly scanning solutions. Our goal is to be agnostic at a high level, strictly speaking using MSDI/MSEL/MSC is not required however is currently
assumed that .NET Platform Extensions are going to be used. In the future this might be broken out.

## Why use Dovetail?

You have to make a choice with every library you introduce, and using Dovetail is no different. If it's not for you, that's okay! Here are some possible reasons why and why not to use Dovetail.

### Reasons to use?

- You can create library code that "just works" without having to ensure that the correct extension method was called, with the correct parameters, for every library you add.
- You can don't have to worry about service registration extension methods in instead each module can setup it's own registrations.
- You can can group bootstrapping logic together to lessen cognitive load.

### Reasons not to use?

Everything has it's positives and negatives. We cannot lie using joints will add time to starting up your application. There is a trade off to be made here
and optimizations that can be made to lessen that trade-off.

Fundamentally if you're making a highly focused, and specialized microservice then using Dovetail may not be for you. You will own the burden
to ensuring that configuration is done the same, extension methods are called, and everything else. It is called "pay-to-play" after all.

#### Note on performance

A quick note on performance. We are now using Source Generators to generate export methods, that return all joints for a given assembly. This allows joint
loading to have similar performance characteristics to pure extension methods, it's still slower but reduces the need to assembly scan.

The <xref:Joinery.Dovetail.ICompiledTypeProvider> is now generated by source generator at compile time, further reducing the need to assembly scan at runtime.

# What is a Dovetail

A joint is nothing but a class that implements the <xref:Joinery.Dovetail.Infrastructure.IDovetailJoint> interface. Nothing special.
By itself <xref:Joinery.Dovetail.Infrastructure.IDovetailJoint> is just a marker interface used to identify a class that may implement one more joints.

Dovetails are then interfaces that are implemented by the class some examples are:

- <xref:Joinery.Dovetail.Configuration.IConfigurationJoint>
- <xref:Joinery.Dovetail.DependencyInjection.IServiceJoint>
- <xref:Joinery.Dovetail.Logging.ILoggingJoint>
- <xref:Joinery.Dovetail.Setup.ISetupJoint>
- <xref:Joinery.Dovetail.Hosting.IHostingDovetail>

ad-hoc Dovetails (or delegate Dovetails) are a different kind of joint but written as a delegate, but they mirror the method given by the Dovetail interface.
These can be used to during program startup just like `ConfigureServices` are used today.

Some examples are:

- <xref:Joinery.Dovetail.Configuration.ConfigurationJoint>
- <xref:Joinery.Dovetail.DependencyInjection.ServiceJoint>
- <xref:Joinery.Dovetail.Logging.LoggingJoint>
- <xref:Joinery.Dovetail.Setup.SetupJoint>
- <xref:Joinery.Dovetail.Hosting.HostingDovetail>

## Exporting a Dovetail

A joint can be exported by using the <xref:Joinery.Dovetail.DovetailAttribute> (eg. `[assembly: Dovetail(typeof(MyDovetail))]`).
This is important you may want to make joints are **not** enabled by default but are available to be loaded by users if they want to.

The rules are straight forward.

- A public joint - Will not be loaded unless it is added to the <xref:Joinery.Dovetail.DovetailContextBuilder>.
- A public exported joint - Will always be loaded unless excluded by assembly or type in the <xref:Joinery.Dovetail.DovetailContextBuilder>.
- A private joint - Will never be loaded. ever.
- A private exported joint - Will always be loaded unless excluded by assembly in the <xref:Joinery.Dovetail.DovetailContextBuilder>.

# Writing your own custom joints

Creating your own joints is fairly easily, and can be done by using existing joints or by executing it yourself.

> [!TIP]
> More information can be found [here](../guides/custom-joints.md)

A package or application that wants to add a new kind of joint declares it with a `<DovetailJoint>` item, and a project the SDK does not
recognise declares its host with a `<DovetailHost>` item. Both are listed, with every value they accept, in the
[reference](../../reference/): [DovetailJoint](../../reference/dovetail-joint/) and [DovetailHost](../../reference/dovetail-host/).