@@ -4,4 +4,206 @@ Modular Go
44[ ![ Go Reference] ( https://pkg.go.dev/badge/github.com/GoCodeAlone/modular.svg )] ( https://pkg.go.dev/github.com/GoCodeAlone/modular )
55
66## Overview
7- Modular is a package that provides a way to create modular applications in Go. It allows you to create modules that can be easily added or removed from the application. It also provides a way to manage dependencies between modules.
7+ Modular is a package that provides a structured way to create modular applications in Go. It allows you to build applications as collections of modules that can be easily added, removed, or replaced. Key features include:
8+
9+ - ** Module lifecycle management** : Initialize, start, and gracefully stop modules
10+ - ** Dependency management** : Automatically resolve and order module dependencies
11+ - ** Service registry** : Register and retrieve application services
12+ - ** Configuration management** : Handle configuration for modules and services
13+ - ** Dependency injection** : Inject required services into modules
14+
15+ ## Installation
16+
17+ ``` go
18+ go get github.com /GoCodeAlone/modular
19+ ```
20+
21+ ## Usage
22+
23+ ### Basic Application
24+
25+ ``` go
26+ package main
27+
28+ import (
29+ " github.com/GoCodeAlone/modular"
30+ " log/slog"
31+ " os"
32+ )
33+
34+ func main () {
35+ // Create a logger
36+ logger := slog.New (slog.NewTextHandler (os.Stdout , nil ))
37+
38+ // Create config provider with application configuration
39+ config := &AppConfig{
40+ Name: " MyApp" ,
41+ Version: " 1.0.0" ,
42+ }
43+ configProvider := modular.NewStdConfigProvider (config)
44+
45+ // Create the application
46+ app := modular.NewApplication (configProvider, logger)
47+
48+ // Register modules
49+ app.RegisterModule (NewDatabaseModule ())
50+ app.RegisterModule (NewAPIModule ())
51+
52+ // Run the application (this will block until the application is terminated)
53+ if err := app.Run (); err != nil {
54+ logger.Error (" Application error" , " error" , err)
55+ os.Exit (1 )
56+ }
57+ }
58+ ```
59+
60+ ### Creating a Module
61+
62+ ``` go
63+ type DatabaseModule struct {
64+ db *sql.DB
65+ config *DatabaseConfig
66+ }
67+
68+ func NewDatabaseModule () modular .Module {
69+ return &DatabaseModule{}
70+ }
71+
72+ // RegisterConfig registers the module's configuration
73+ func (m *DatabaseModule ) RegisterConfig (app *modular .Application ) {
74+ m.config = &DatabaseConfig{
75+ DSN: " postgres://user:password@localhost:5432/dbname" ,
76+ }
77+ app.RegisterConfigSection (" database" , modular.NewStdConfigProvider (m.config ))
78+ }
79+
80+ // Name returns the module's unique name
81+ func (m *DatabaseModule ) Name () string {
82+ return " database"
83+ }
84+
85+ // Dependencies returns other modules this module depends on
86+ func (m *DatabaseModule ) Dependencies () []string {
87+ return []string {} // No dependencies
88+ }
89+
90+ // Init initializes the module
91+ func (m *DatabaseModule ) Init (app *modular .Application ) error {
92+ // Initialize database connection
93+ db , err := sql.Open (" postgres" , m.config .DSN )
94+ if err != nil {
95+ return err
96+ }
97+ m.db = db
98+ return nil
99+ }
100+
101+ // ProvidesServices returns services provided by this module
102+ func (m *DatabaseModule ) ProvidesServices () []modular .ServiceProvider {
103+ return []modular.ServiceProvider {
104+ {
105+ Name: " database" ,
106+ Description: " Database connection" ,
107+ Instance: m.db ,
108+ },
109+ }
110+ }
111+
112+ // RequiresServices returns services required by this module
113+ func (m *DatabaseModule ) RequiresServices () []modular .ServiceDependency {
114+ return []modular.ServiceDependency {} // No required services
115+ }
116+
117+ // Start starts the module
118+ func (m *DatabaseModule ) Start (ctx context .Context ) error {
119+ return nil // Database is already connected
120+ }
121+
122+ // Stop stops the module
123+ func (m *DatabaseModule ) Stop (ctx context .Context ) error {
124+ return m.db .Close ()
125+ }
126+ ```
127+
128+ ### Service Dependencies
129+
130+ ``` go
131+ // A module that depends on another service
132+ func (m *APIModule ) RequiresServices () []modular .ServiceDependency {
133+ return []modular.ServiceDependency {
134+ {
135+ Name: " database" ,
136+ Required: true , // Application won't start if this service is missing
137+ },
138+ {
139+ Name: " cache" ,
140+ Required: false , // Optional dependency
141+ },
142+ }
143+ }
144+
145+ // Using constructor injection
146+ func (m *APIModule ) Constructor () modular .ModuleConstructor {
147+ return func (app *modular.Application , services map [string ]any) (modular.Module , error ) {
148+ // Services that were requested in RequiresServices() are available here
149+ db := services[" database" ].(*sql.DB )
150+
151+ // Create a new module instance with injected services
152+ return &APIModule{
153+ db: db,
154+ }, nil
155+ }
156+ }
157+ ```
158+
159+ ### Configuration Management
160+
161+ ``` go
162+ // Define your configuration struct
163+ type AppConfig struct {
164+ Name string ` json:"name" yaml:"name"`
165+ Version string ` json:"version" yaml:"version"`
166+ }
167+
168+ // Implement ConfigSetup interface if needed
169+ func (c *AppConfig ) Setup () error {
170+ // Validate configuration or set defaults
171+ if c.Name == " " {
172+ c.Name = " DefaultApp"
173+ }
174+ return nil
175+ }
176+ ```
177+
178+ ## Key Interfaces
179+
180+ ### Module
181+
182+ The core interface that all modules must implement:
183+
184+ ``` go
185+ type Module interface {
186+ RegisterConfig (app *Application)
187+ Init (app *Application) error
188+ Start (ctx context.Context ) error
189+ Stop (ctx context.Context ) error
190+ Name () string
191+ Dependencies () []string
192+ ProvidesServices () []ServiceProvider
193+ RequiresServices () []ServiceDependency
194+ }
195+ ```
196+
197+ ### ConfigProvider
198+
199+ Interface for configuration providers:
200+
201+ ``` go
202+ type ConfigProvider interface {
203+ GetConfig () any
204+ }
205+ ```
206+
207+ ## License
208+
209+ [ MIT License] ( LICENSE )
0 commit comments