Register Service Modules

Group related services into modules in Parsley to improve code organization, reusability, and separation of concerns.

Parsley provides a convenient way to group related services into modules using the RegisterModule method. This method allows you to register a function that bundles service registrations, making your code more organized and maintainable. Here's how to use it:

package main

import (
	"context"

	"github.com/matzefriedrich/parsley-docs/examples/registration-concepts/internal"
	"github.com/matzefriedrich/parsley/pkg/registration"
	"github.com/matzefriedrich/parsley/pkg/resolving"
	"github.com/matzefriedrich/parsley/pkg/types"
)

func main() {

	ctx := context.Background()

	registry := registration.NewServiceRegistry()
	registry.RegisterModule(greeterModule)

	resolver := resolving.NewResolver(registry)
	resolverContext := resolving.NewScopedContext(ctx)
	greeter, _ := resolving.ResolveRequiredService[internal.Greeter](resolverContext, resolver)
	greeter.SayHello("John", false)
}

func greeterModule(registry types.ServiceRegistry) error {
	registry.Register(internal.NewGreeterFactory("Hi"), types.LifetimeTransient)
	return nil
}

Conditional Module Registration

Sometimes, you might want to register a module only if a certain condition is met (e.g., based on environment variables or configuration). For this, Parsley provides the RegisterModuleIf method:

registry := registration.NewServiceRegistry()
isDev := os.Getenv("ENV") == "development"

// Register the DebugModule only in a development environment
_ = registry.RegisterModuleIf(isDev, DebugModule)

Benefits

Using RegisterModule offers several benefits. It helps maintain a clean and organized code structure by grouping related services, making the codebase more straightforward to manage.

Modules allow you to define and reuse service groupings across different parts of your application, promoting modularity and reusability. Additionally, this approach keeps the service registration logic separate from the application logic, enhancing the separation of concerns and improving overall code maintainability and clarity as your application scales.

Another use case is a package that keeps all service implementation types private while exporting only interfaces and module registration functions. This way, services can be integrated into applications without exposing their implementation details.