Issue 1:
Don't you think the dependency injection framework needs a singleton type?

I checked the documentation and as I can see there is no option for creating a class as a singleton. If I want to pass in a class as a dependency it will be created every time. So a feature to create singleton and if that already exists just pass it in as a dependency would be great. Because if you create a huge dependency tree than you have to specify one-by-one to make singletons.

Maybe I missed something how to do that but if not that could be a new feature.

Issue 2:
Example

Must install qcelemental first! Pardon that I'm not able to take the core issues and create a simpler example without this external package; however, this demonstrates the core problem well.

pip install qcelemental

from pydantic import BaseModel
from fastapi.encoders import jsonable_encoder
from qcelemental.models import Molecule
from numpy import array, ndarray

molecule_data = {
"schema_name": "qcschema_molecule",
"schema_version": 2,
"validated": True,
"symbols": array(["O", "H", "H"], dtype="<U1"),
"geometry": array(
[
[0.0, 0.0, 0.0],
[0.52421003, 1.68733646, 0.48074633],
[1.14668581, -0.45032174, -1.35474466],
]
),
"name": "IUPAC oxidane",
"molecular_charge": 0.0,
"molecular_multiplicity": 1,
"fix_com": False,
"fix_orientation": False,
"provenance": {
"creator": "QCElemental",
"version": "v0.17.0",
"routine": "qcelemental.molparse.from_string",
},
}

class NestedMolecule(BaseModel):
molecule: Molecule

class NestedMoleculeRepeatedEncoders(NestedMolecule):
class Config:
json_encoders = {ndarray: lambda x: x.tolist()}

molecule = Molecule.parse_obj(molecule_data)
nested_molecule_repeat_encoders = NestedMoleculeRepeatedEncoders(molecule=molecule)
nested_molecule = NestedMolecule(molecule=molecule)

# Works great! Fastapi picks up the custom encoders/serialization methods on Molecule and can encode the object and ultimately return a JSONResponse (if this were the response_model on a path)
jsonable_encoder(molecule)

# Works! But why do I have to duplicate these encoders that already exist on the Molecule object??
jsonable_encoder(nested_molecule_repeat_encoders)

# Fails to properly encode numpy.ndarray field at nested_molecule.molecule.geometry. A JSONResponse with response_model=NestedMolecule would fail.
jsonable_encoder(nested_molecule)

Description

Fastapi appears to correctly utilize the custom json encoding/serialization methods found on Molecule. Great! However, if I nest a Molecule inside another Pydantic model, fastapi does not correctly pick up these serialization customizations. In order to use a NestedMolecule I have to add custom json_encoders to the Config class, as seen on NestedMoleculeRepeatedEncoders. But why do I have to do this? Seems fastapi should pick up the custom encoders on nested Pydantic objects just like it does on the original Molecule object. I believe this is a bug.

One way to help see what's going on here is to add print(type(obj), obj) on line 37 of fastapi.encoders to see how the jsonable_encoder function is correctly handing the first two cases and fails the third case.

Environment

OS: MacOS:

FastAPI Version 0.62.0:

Python version: 3.9.0