Skip to main content

A minimalistic and easy to use Dependency Injection Framework.

Project description

minidi

A minimalistic and easy to use Dependency Injection Framework. Dependency Injection should help clean up code, reduce coupling, increase cohesion and simplify setups and cleanups of unittests.

Usage

canUserAccessFile = FileSystemAccessDetector.canUserAccessFile(userId=1, file='some/path/to/file.txt')

This static code is easy to access, but since the dependencies the FileSystemAccessDetector relies on are hard coded into it, we cannot test the class itself without testing all underlying dependencies with it.

pFileSystemAccessDetector = FileSystemAccessDetector()
pFileSystemAccessDetector.pFileShareRegister = pFileShareRegister # some instance used earlier already
pFileSystemAccessDetector.pFileSystem = FileSystem()
canUserAccessFile = pFileSystemAccessDetector.canUserAccessFile(userId=1, file='some/path/to/file.txt')

The non-static approach is already better, since we now have influence over the code we give the FileSystemAccessDetector to work with, essentially enabling dependency injection, but this would be tedious to write. Just imagine a logic class needing 6 different dependencies ... if only we could save time, somehow ...?

pFileSystemAccessDetector = minidi.get(FileSystemAccessDetector)
canUserAccessFile = pFileSystemAccessDetector.canUserAccessFile(userId=1, file='some/path/to/file.txt')

And we are done. Simple, isn't it? Now how can we make this magic happen?

  1. FileSystemAccessDetector is derived from the empty Interface minidi.Injectable
  2. we annotate our dependencies, which have to be Injectable as well
  3. we code our logic functions as we would normally do
class FileSystemAccessDetector(minidi.Injectable):
	# injectables, get initialized via minidi.get if you call minidi.get(FileSystemAccessDetector)
	pFileShareRegister: FileShareRegister
	pFileSystem: FileSystem
	
	def canUserAccessFile(self, userId: int, file: str) -> bool:
		[...] # other dependencies available in self.pFileShareRegister and self.pFileSystem

This implementation opens up the code to be tested without the need of a real FileShareRegister or FileSystem, and therefor also a real file.

class TestFileSystemAccessDetector(unittest.TestCase):
	def test_CanUserAccessFile(self):
		# we don't want to initialize the dependencies over minidi.get,
		# this would keep the problems the exact same as with static code;
		# instead we mock to fake underlying functionality to only test what we want to test here
		pFileShareRegister = FileShareRegister()
		pFileShareRegister.getSharedUserIds = unittest.mock.Mock(return_value=[1,2,5,7])

		pFileSystem = FileSystem()
		pFileSystem.getOwnerUserId = unittest.mock.Mock(return_value=3)
		pFileSystem.isPublicFile = unittest.mock.Mock(return_value=False)
		pFileSystem.isProtectedFile = unittest.mock.Mock(return_value=True)
		pFileSystem.isPrivateFile = unittest.mock.Mock(return_value=False)

		pFileSystemAccessDetector = FileSystemAccessDetector()
		# the dependencies get injected from the outside right here
		pFileSystemAccessDetector.pFileShareRegister = pFileShareRegister
		pFileSystemAccessDetector.pFileSystem = pFileSystem

		[...] # run test with assertions

And boom, easy maintainable code with less hard coded dependencies.

Technical Information

  • you CANNOT give an Injectable any other member other than Injectables (except for non-annotated constants), they are designed to work stateless like global functions with the benefit of replaceability
  • minidi.get can only fill the dependencies you have annotated in your class
  • minidi will hold all created Injectables indefinitely, until your program gets terminated; still better than static code, which will be allocated on the programs start
  • minidi.set allows to use different implementations of classes depending on your runtime environment

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

minidi-1.1.1.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

minidi-1.1.1-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file minidi-1.1.1.tar.gz.

File metadata

  • Download URL: minidi-1.1.1.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.2

File hashes

Hashes for minidi-1.1.1.tar.gz
Algorithm Hash digest
SHA256 51c97564052a822c0ab7c98d2271c42c8107b9c6a5bb46c3a299088cf6d3841f
MD5 28613ba5525d3793abd3980bac900fca
BLAKE2b-256 6f408c1c61def7457520aed4f06bb5e62e6fceb3f33227d3566e6e3a71e14299

See more details on using hashes here.

File details

Details for the file minidi-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: minidi-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.2

File hashes

Hashes for minidi-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f362aa6ddcd6200928a853de43c7cd44870f3d2ad62cd0abb18e59cbba2788de
MD5 6722875756c9a20a82450d4140d716b6
BLAKE2b-256 fe6f6b845c2563bd07fe475c718b666da4cfb097135ecb7c9a844bfef7946378

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page