Dependency injection library for Lua that supports constructor based injection.
- Map constructor parameter names to Lua packages and constant values
- Configure providers to dynamically build parameter types
- Support for configuring types to be kept in singleton scope
- Zero configuration/customisation of application required, exept for main module configuration itself
Get this library using luarocks: http://luarocks.org/modules/djfdyuruiry/lua-di
Given you have the following classes:
-- example/Printer.lua
local Printer = {}
Printer.__index = Printer
function Printer.new()
return setmetatable({}, Printer)
end
function Printer.write(self, ...)
print(...)
end
return Printer
-- example/App.lua
local App = {}
App.__index = App
function App.new(appConfig, printer, writer, message)
return setmetatable(
{
appConfig = appConfig,
printer = printer,
writer = writer,
message = message
}, App)
end
function App.run(self)
self.printer:write("Hello World")
self.writer(self.message)
print(self.appConfig.logPath)
end
return App
You can configure all your dependencies in one function, then build your application:
local DependencyInjectionModule = require "lua-di.DependencyInjectionModule"
-- build and configure your app module
local appModule = DependencyInjectionModule(function(config)
-- bind constructor parameter names to Lua modules
config.bindings.types.printer = "example.Printer"
-- bind constructor parameter to constant value
config.bindings.values.message = "Orders Recieved Captain"
-- parameter values can be of any type
config.bindings.values.writer = function(...)
print(...)
end
-- bind constructor parameter name to custom type (not a Lua module)
config.bindings.types.appConfig = "AppConfig"
-- define a provider for your custom type (either a builder function or a constant)
-- (you can also provide instances for a Lua Package name in config.providers if you wish)
config.providers.AppConfig = function()
return
{
logPath = "/var/log/app.log",
counter = 5
}
end
-- make injected AppConfig instance a singleton
config.singletons.AppConfig = true
end)
-- build an instance of the entry point class, injecting your dependencies
local app = appModule.getInstance("example.App")
app:run()
You can also enable the auto configure option to parse Lua modules using parameter names, following the pattern module__full__path__type
for your constructor parameters; note this is case sensitive.
Given this class:
-- example/AutoApp.lua
local AutoApp = {}
AutoApp.__index = AutoApp
function AutoApp.new(example__Printer)
return setmetatable(
{
-- given there exists a class in 'example/Printer.lua'
printer = example__Printer
}, AutoApp)
end
function AutoApp.run(self)
self.printer:write("Auto Hello World")
end
return AutoApp
You can enable autoconfiguration like so:
local DependencyInjectionModule = require "lua-di.DependencyInjectionModule"
local autoAppModule = DependencyInjectionModule(function(config)
config.enableAutoConfiguration()
end)
local autoApp = autoAppModule.getInstance("example.AutoApp")
autoApp:run()
Note this library supports both standard Lua classes and functional style classes:
Lua Classes
-- SomeClass.lua
local SomeClass = {}
SomeClass.__index = SomeClass
function SomeClass.new(val)
return setmetatable({}, SomeClass)
end
function SomeClass.method(self)
-- do stuff
end
return SomeClass
declaration: local instance = SomeClass.new(val)
Functional Style
local SomeClass = function(val)
local iAmPrivate = "secretStuff"
local method = function()
-- do stuff
end
return
{
method = method
}
end
return SomeClass
declaration: local instance = SomeClass(val)
See the example app in example.lua
to get a full view of how to configure an application to use this Dependency injection library.