Page MenuHomeWildfire Games
Paste P274

Dependency Injection
ActivePublic

Authored by lyv on Jun 3 2022, 2:31 PM.
Tags
None
Referenced Files
F2767437: Dependency Injection
Jun 3 2022, 2:31 PM
Subscribers
None
const Injector = new class
{
constructor()
{
this.services = new WeakMap();
this.objectCache = new WeakMap();
}
registerService(___)
{
let TService = arguments[0];
let TServiceArgs = [];
if (arguments.length > 1)
{
for (let i = 1; i < arguments.length; ++i)
{
TServiceArgs.push(arguments[i]);
}
}
let args = [null].concat(TServiceArgs);
let instance = new (Function.prototype.bind.apply(TService, args));
this.services.set(TService, instance);
}
getService(TService)
{
if (this.services.has(TService))
{
return this.services.get(TService);
}
else
{
error("No service of " + TService.name + " is registered");
}
}
get(___)
{
let TObject = arguments[0];
let TObjectArgs = [];
if (arguments.length > 1)
{
for (let i = 1; i < arguments.length; ++i)
{
TObjectArgs.push(arguments[i]);
}
}
if (!TObject.deps)
{
error("The class " + TObject.name + " does not define any dependencies");
}
let services = [];
if (!this.objectCache.has(TObject))
{
for (let dep of TObject.deps)
{
if (this.services.has(dep))
{
services.push(this.services.get(dep));
}
else
{
error("Can't resolve dependency " + dep.name + " for " + TObject.name);
}
}
this.objectCache.set(TObject, services);
}
else
{
services = this.objectCache.get(TObject);
}
let args = [null].concat(services).concat(TObjectArgs);
let instance = new (Function.prototype.bind.apply(TObject, args));
return instance;
}
};

Event Timeline

Seemed interesting from an old branch although I don't think this was a good idea, just an experiment that didn't work out.

This is done to match .net core's dependency injection thing IIRC, long time since this was written, longer since I looked at .net core.

I believe this was abandoned because it does not change the semantics, just the syntax, and the new syntax becomes excessively verbose.
Moreover, it might be counter productive because the fact that RandomMap is globally mutable singleton is now hidden behind a layer of indirection.
However, it makes the coupling less rigid. You don't have to define a constant identified as g_Map if the resolution of the singleton is automatic.

The rationale for not doing some Singleton type class for RandomMap was to allow other dependent placers and painters to receive the instance as a parameter. Which is the whole Injector.get thingy.

// const g_Map = new RandomMap(heightLand, tMainTerrain);
// doThing(g_Map);

Injector.registerService(RandomMap, heightLand, tMainTerrain);
doThing(Injector.getService(RandomMap));
Stan changed the visibility from "All Users" to "Public (No Login Required)".Jun 3 2022, 6:16 PM