di

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2025 License: MIT Imports: 11 Imported by: 0

README

Dependency Injection Package

Overview

The di package provides a container-based dependency injection system for Go applications. It helps manage dependencies between components, making your code more modular, testable, and maintainable.

Features

  • Container Types:

    • Base container
    • Service container
    • Repository container
    • Generic container
  • Features:

    • Constructor injection
    • Type-safe dependency management with generics
    • Context-aware containers
    • Structured configuration support
    • Domain-driven design support

Installation

go get github.com/abitofhelp/servicelib/di

Quick Start

See the Basic Usage Example for a complete, runnable example of how to use the di package.

Configuration

See the Service Container Example for a complete, runnable example of how to configure the di package.

API Documentation

Core Types
BaseContainer

The BaseContainer is the foundation for all container types. It provides access to common dependencies like context, logger, and configuration.

See the Basic Usage Example for a complete, runnable example of how to use the BaseContainer.

ServiceContainer

The ServiceContainer is designed for domain-driven design applications. It manages repositories, domain services, and application services.

See the Service Container Example for a complete, runnable example of how to use the ServiceContainer.

GenericAppContainer

The GenericAppContainer provides a flexible container for any application structure. It allows custom initialization of repositories, domain services, and application services.

See the Generic Container Example for a complete, runnable example of how to use the GenericAppContainer.

Key Methods
NewBaseContainer

The NewBaseContainer function creates a new base container with context, logger, and configuration.

baseContainer, err := di.NewBaseContainer(ctx, logger, cfg)
NewContainer

The NewContainer function creates a new generic container with context, logger, and configuration.

container, err := di.NewContainer(ctx, logger, cfg)
NewServiceContainer

The NewServiceContainer function creates a new service container with context, logger, configuration, repository, and service initializers.

container, err := di.NewServiceContainer(ctx, logger, cfg, repo, initDomainService, initAppService)
NewGenericAppContainer

The NewGenericAppContainer function creates a new generic application container with context, logger, configuration, connection string, and initializers.

container, err := di.NewGenericAppContainer(ctx, logger, cfg, connectionString, initRepo, initDomainService, initAppService)

Examples

For complete, runnable examples, see the following files in the examples directory:

Best Practices

  1. Use Interfaces: Define clear interfaces for your repositories, domain services, and application services.

  2. Type Safety: Use generics to ensure type safety in your dependency injection.

  3. Context Awareness: Pass context through your application to enable proper cancellation and timeout handling.

  4. Configuration: Use structured configuration objects rather than loose key-value pairs.

  5. Domain-Driven Design: Organize your code according to domain-driven design principles with clear separation between repositories, domain services, and application services.

  6. Error Handling: Always check for errors when creating containers and initializing dependencies.

  7. Testing: Use dependency injection to make your code more testable by allowing mock implementations.

Troubleshooting

Common Issues
Container Creation Failures

Issue: Errors when creating a container.

Solution: Ensure that you're providing valid context, logger, and configuration objects. Check that your configuration implements the required interfaces.

Dependency Initialization Failures

Issue: Errors when initializing dependencies.

Solution: Check that your initializer functions are correctly implemented and handle all possible error cases. Ensure that dependencies are available before trying to use them.

Type Mismatches

Issue: Type assertion errors when using container methods.

Solution: Use the correct generic type parameters when creating containers. Ensure that your types implement the required interfaces.

  • Config - The config component is used to configure the di package.
  • Logging - The logging component is used for logging in the di package.
  • Context - The context component is used for context management in the di package.

Contributing

Contributions to this component are welcome! Please see the Contributing Guide for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package di provides a generic dependency injection container that can be used across different applications.

Package di provides a generic dependency injection container that can be used across different applications.

Package di provides generic database initializers that can be used across different applications.

Package di provides a generic dependency injection container that can be used across different applications.

Package di provides a generic dependency injection container that can be used across different applications.

Package di provides generic repository interfaces that can be used across different applications.

Package di provides a generic dependency injection container that can be used across different applications.

Package di provides repository initializers for different database types.

Package di provides a generic dependency injection container that can be used across different applications.

Index

Constants

View Source
const DefaultTimeout = 30 * time.Second

Default timeout for database operations

Variables

This section is empty.

Functions

func GenericMongoInitializer

func GenericMongoInitializer(
	ctx context.Context,
	uri string,
	databaseName string,
	collectionName string,
	zapLogger *zap.Logger,
) (interface{}, error)

GenericMongoInitializer initializes a MongoDB collection and returns it This can be used by applications to create their own repository initializers

func GenericPostgresInitializer

func GenericPostgresInitializer(
	ctx context.Context,
	dsn string,
	zapLogger *zap.Logger,
) (interface{}, error)

GenericPostgresInitializer initializes a PostgreSQL connection pool and returns it This can be used by applications to create their own repository initializers

func GenericSQLiteInitializer

func GenericSQLiteInitializer(
	ctx context.Context,
	uri string,
	zapLogger *zap.Logger,
) (interface{}, error)

GenericSQLiteInitializer initializes a SQLite database connection and returns it This can be used by applications to create their own repository initializers

func MongoDBInitializer

func MongoDBInitializer(
	ctx context.Context,
	uri string,
	databaseName string,
	collectionName string,
	logger *zap.Logger,
) (*mongo.Collection, error)

MongoDBInitializer initializes a MongoDB client and collection

func PostgresInitializer

func PostgresInitializer(
	ctx context.Context,
	dsn string,
	logger *zap.Logger,
) (*pgxpool.Pool, error)

PostgresInitializer initializes a PostgreSQL connection pool

func SQLiteInitializer

func SQLiteInitializer(
	ctx context.Context,
	uri string,
	logger *zap.Logger,
) (*sql.DB, error)

SQLiteInitializer initializes a SQLite database connection

Types

type AppRepositoryInitializer

type AppRepositoryInitializer[T any] func(ctx context.Context, connectionString string, logger *zap.Logger) (T, error)

AppRepositoryInitializer is a function type that initializes a repository

type ApplicationService

type ApplicationService interface {
	// GetID returns the application service ID
	GetID() string
}

ApplicationService is a generic interface for application services

type ApplicationServiceInitializerFunc

type ApplicationServiceInitializerFunc[R Repository, D DomainService, A ApplicationService] func(
	domainService D,
	repository R,
) (A, error)

ApplicationServiceInitializerFunc is a function type that initializes an application service

type BaseContainer

type BaseContainer[C any] struct {
	// contains filtered or unexported fields
}

BaseContainer is a generic dependency injection container that can be embedded in other containers

func NewBaseContainer

func NewBaseContainer[C any](ctx context.Context, logger *zap.Logger, cfg C) (*BaseContainer[C], error)

NewBaseContainer creates a new base dependency injection container

func (*BaseContainer[C]) Close

func (c *BaseContainer[C]) Close() error

Close closes all resources

func (*BaseContainer[C]) GetConfig

func (c *BaseContainer[C]) GetConfig() C

GetConfig returns the configuration

func (*BaseContainer[C]) GetContext

func (c *BaseContainer[C]) GetContext() context.Context

GetContext returns the context

func (*BaseContainer[C]) GetContextLogger

func (c *BaseContainer[C]) GetContextLogger() *logging.ContextLogger

GetContextLogger returns the context logger

func (*BaseContainer[C]) GetLogger

func (c *BaseContainer[C]) GetLogger() *zap.Logger

GetLogger returns the logger

func (*BaseContainer[C]) GetValidator

func (c *BaseContainer[C]) GetValidator() *validator.Validate

GetValidator returns the validator

type Container

type Container struct {
	*BaseContainer[interface{}]
}

Container is a generic dependency injection container for backward compatibility It uses the BaseContainer with an interface{} config type

func NewContainer

func NewContainer(ctx context.Context, logger *zap.Logger, cfg interface{}) (*Container, error)

NewContainer creates a new generic dependency injection container This function is kept for backward compatibility

func (*Container) GetRepositoryFactory

func (c *Container) GetRepositoryFactory() interface{}

GetRepositoryFactory returns the repository factory This is a placeholder method that should be overridden by derived containers

type DomainService

type DomainService interface {
	// GetID returns the domain service ID
	GetID() string
}

DomainService is a generic interface for domain services

type DomainServiceInitializerFunc

type DomainServiceInitializerFunc[R Repository, D DomainService] func(repository R) (D, error)

DomainServiceInitializerFunc is a function type that initializes a domain service

type GenericAppContainer

type GenericAppContainer[R any, D any, A any, C any] struct {
	*BaseContainer[C]
	// contains filtered or unexported fields
}

GenericAppContainer is a generic dependency injection container for any application

func NewGenericAppContainer

func NewGenericAppContainer[R any, D any, A any, C any](
	ctx context.Context,
	logger *zap.Logger,
	cfg C,
	connectionString string,
	initRepo AppRepositoryInitializer[R],
	initDomainService GenericDomainServiceInitializer[R, D],
	initAppService GenericApplicationServiceInitializer[R, D, A],
) (*GenericAppContainer[R, D, A, C], error)

NewGenericAppContainer creates a new generic application container

func (*GenericAppContainer[R, D, A, C]) Close

func (c *GenericAppContainer[R, D, A, C]) Close() error

Close closes all resources

func (*GenericAppContainer[R, D, A, C]) GetApplicationService

func (c *GenericAppContainer[R, D, A, C]) GetApplicationService() A

GetApplicationService returns the application service

func (*GenericAppContainer[R, D, A, C]) GetDomainService

func (c *GenericAppContainer[R, D, A, C]) GetDomainService() D

GetDomainService returns the domain service

func (*GenericAppContainer[R, D, A, C]) GetRepository

func (c *GenericAppContainer[R, D, A, C]) GetRepository() R

GetRepository returns the repository

func (*GenericAppContainer[R, D, A, C]) GetRepositoryFactory

func (c *GenericAppContainer[R, D, A, C]) GetRepositoryFactory() interface{}

GetRepositoryFactory returns the repository as an interface{}

type GenericApplicationServiceInitializer

type GenericApplicationServiceInitializer[R any, D any, A any] func(domainService D, repository R) (A, error)

GenericApplicationServiceInitializer is a function type that initializes an application service

type GenericDomainServiceInitializer

type GenericDomainServiceInitializer[R any, D any] func(repository R) (D, error)

GenericDomainServiceInitializer is a function type that initializes a domain service

type GenericRepositoryContainer

type GenericRepositoryContainer[T any, C any] struct {
	*BaseContainer[C]
	// contains filtered or unexported fields
}

GenericRepositoryContainer is a generic dependency injection container for any repository type

func NewGenericRepositoryContainer

func NewGenericRepositoryContainer[T any, C any](
	ctx context.Context,
	logger *zap.Logger,
	cfg C,
	entityType string,
	initRepo GenericRepositoryInitializer[T],
) (*GenericRepositoryContainer[T, C], error)

NewGenericRepositoryContainer creates a new generic repository container

func (*GenericRepositoryContainer[T, C]) Close

func (c *GenericRepositoryContainer[T, C]) Close() error

Close closes all resources

func (*GenericRepositoryContainer[T, C]) GetRepository

func (c *GenericRepositoryContainer[T, C]) GetRepository() T

GetRepository returns the repository

func (*GenericRepositoryContainer[T, C]) GetRepositoryFactory

func (c *GenericRepositoryContainer[T, C]) GetRepositoryFactory() interface{}

GetRepositoryFactory returns the repository as an interface{}

type GenericRepositoryInitializer

type GenericRepositoryInitializer[T any] func(ctx context.Context, connectionString string, logger *zap.Logger) (T, error)

GenericRepositoryInitializer is a function type that initializes a repository

type Repository

type Repository interface {
	// GetID returns the repository ID
	GetID() string
}

Repository is a generic interface for repositories

type RepositoryContainer

type RepositoryContainer[T any] struct {
	// contains filtered or unexported fields
}

RepositoryContainer is a generic dependency injection container for any repository type

func NewRepositoryContainer

func NewRepositoryContainer[T any](
	ctx context.Context,
	logger *zap.Logger,
	cfg config.Config,
	entityType string,
	initRepo RepositoryInitializerFunc[T],
) (*RepositoryContainer[T], error)

NewRepositoryContainer creates a new repository container

func (*RepositoryContainer[T]) Close

func (c *RepositoryContainer[T]) Close() error

Close closes all resources

func (*RepositoryContainer[T]) GetConfig

func (c *RepositoryContainer[T]) GetConfig() config.Config

GetConfig returns the configuration

func (*RepositoryContainer[T]) GetContext

func (c *RepositoryContainer[T]) GetContext() context.Context

GetContext returns the context

func (*RepositoryContainer[T]) GetLogger

func (c *RepositoryContainer[T]) GetLogger() *zap.Logger

GetLogger returns the logger

func (*RepositoryContainer[T]) GetRepository

func (c *RepositoryContainer[T]) GetRepository() T

GetRepository returns the repository

func (*RepositoryContainer[T]) GetRepositoryFactory

func (c *RepositoryContainer[T]) GetRepositoryFactory() interface{}

GetRepositoryFactory returns the repository as an interface{}

type RepositoryInitializerFunc

type RepositoryInitializerFunc[T any] func(
	ctx context.Context,
	connectionString string,
	databaseName string,
	collectionName string,
	logger *zap.Logger,
) (T, error)

RepositoryInitializerFunc is a function type that initializes a repository

type ServiceContainer

type ServiceContainer[R Repository, D DomainService, A ApplicationService, C config.Config] struct {
	*BaseContainer[C]
	// contains filtered or unexported fields
}

ServiceContainer is a generic dependency injection container for services

func NewServiceContainer

func NewServiceContainer[R Repository, D DomainService, A ApplicationService, C config.Config](
	ctx context.Context,
	logger *zap.Logger,
	cfg C,
	repository R,
	initDomainService DomainServiceInitializerFunc[R, D],
	initAppService ApplicationServiceInitializerFunc[R, D, A],
) (*ServiceContainer[R, D, A, C], error)

NewServiceContainer creates a new service container

func (*ServiceContainer[R, D, A, C]) Close

func (c *ServiceContainer[R, D, A, C]) Close() error

Close closes all resources

func (*ServiceContainer[R, D, A, C]) GetApplicationService

func (c *ServiceContainer[R, D, A, C]) GetApplicationService() A

GetApplicationService returns the application service

func (*ServiceContainer[R, D, A, C]) GetDomainService

func (c *ServiceContainer[R, D, A, C]) GetDomainService() D

GetDomainService returns the domain service

func (*ServiceContainer[R, D, A, C]) GetRepository

func (c *ServiceContainer[R, D, A, C]) GetRepository() R

GetRepository returns the repository

func (*ServiceContainer[R, D, A, C]) GetRepositoryFactory

func (c *ServiceContainer[R, D, A, C]) GetRepositoryFactory() interface{}

GetRepositoryFactory returns the repository as an interface{}

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL