** Use to define an IoC service.** ** pre>** syntax: fantom** serviceBuilder := regBuilder.addService()** serviceBuilder** .withId("acme::penguins")** .withType(Penguins#)** .withImplType(PenguinsImpl#)** .withScope("root")** <pre** ** The above could be inlined and, taking advantage of defaults, could be shortened to just:** ** pre>** syntax: fantom** regBuilder.addService(Penguins#).withRootScope** <pre@Jsmixin ServiceBuilder {** Sets the unique service ID.** If not set explicitly it is taken to be the qualified Type name.** ** pre>** syntax: fantom** regBuilder.addService.withId("thread")** <preabstract This withId(Str? id)** Sets the type of the service. May also be set via 'addService()'. ** ** pre>** syntax: fantom** regBuilder.addService(Penguin#)** ** regBuilder.addService.withType(Penguin#)** <pre** ** If the service type is a mixin then either an implementation type or a builder must be subsequently set.** ** pre>** syntax: fantom** regBuilder.addService(IPenguin#).withImplType(PenguinImpl#)** <pre** abstract This withType(Type type)** Sets the implementation of the service. Used when the service is autobuilt. May also be set via 'addService()'.** ** pre>** syntax: fantom** regBuilder.addService(IPenguin#, PenguinImpl#)** ** regBuilder.addService(Penguin#).withImplType(PenguinImpl#)** <pre** ** 'ImplType' is used, along with 'ctorArgs' and 'fieldVals' to autobuild an instance of the service.abstract This withImplType(Type? implType)** Creates an alias ID that this service is also known as.** ** pre>** syntax: fantom** reg := regBuilder { ** addService(Wolf#).withAlias("acme::Sheep") ** }.build** ** reg.rootScope.serviceById("acme::Wolf")** ** reg.rootScope.serviceById("acme::Sheep") // --> same service as 'acme::wolf'** <preabstract This withAlias(Str alias)** Creates multiple aliases that this service is also known as.abstract This withAliases(Str[]? aliases)** Adds an alias Type that this service is also known as.** ** pre>** syntax: fantom** reg := regBuilder { ** addService(Wolf#).withAliasType(Sheep#) ** }.build** ** reg.rootScope.serviceByType(Wolf#)** ** reg.rootScope.serviceByType(Sheep#) // --> same service as Wolf** <preabstract This withAliasType(Type aliasType)** Sets many Types that this service is also known as.abstract This withAliasTypes(Type[]? aliasTypes)** Sets the scope that the service can be created in.** ** pre>** syntax: fantom** regBuilder.addService(Wolf#).withScope("thread")** <preabstract This withScope(Str scope)** Sets multiple scopes that the service can be created in.** ** pre>** syntax: fantom** regBuilder.addService(Wolf#).withScopes(["root", "thread"])** <preabstract This withScopes(Str[]? scopes)** Convenience for 'withScope("root")'. ** ** pre>** syntax: fantom** regBuilder.addService(Wolf#).withRootScope** <preabstract This withRootScope()** Sets a func that creates instances of the services. ** ** pre>** syntax: fantom** regBuilder.addService(Wolf#).withBuilder |Scope scope -> Obj?| {** return Penguin()** }** <pre** ** 'Scope' is the current scope the service is being built in.abstract This withBuilder(|Scope -> Obj?|? serviceBuilder)** Set constructor arguments to be used when the service is autobuilt. ** Note the args must be immutable.** ** pre>** syntax: fantom** regBuilder.addService(Penguin#).withCtorArgs([arg1, arg2])** <preabstract This withCtorArgs(Obj?[]? args)** Set field values to used when the service is autobuilt. ** An alternative to using ctor args. ** Note all vals must be immutable.** ** pre>** syntax: fantom** regBuilder.addService(Penguin#).withFieldVals([Penguin#arg1 : "val1", Penguin#arg2 : "val2"])** <preabstract This withFieldVals([Field:Obj?]? fieldVals)}@Jsinternalclass ServiceBuilderImpl : ServiceBuilder {internal SrvDef srvDefinternalnew make(Type moduleId){this.srvDef = SrvDef {it.moduleId = moduleId}}override This withId(Str? serviceId){ srvDef.id = serviceIdreturnthis}override This withType(Type serviceType){ srvDef.type = serviceType.toNonNullableif(srvDef.id == null) srvDef.id = serviceType.qnameif(srvDef.builder == null) srvDef.autobuild = truereturnthis}override This withImplType(Type? serviceImplType){if(serviceImplType != null && serviceImplType.isMixin)throw ArgErr(ErrMsgs.autobuilder_bindImplNotClass(serviceImplType)) srvDef.implType = serviceImplType?.toNonNullableif(serviceImplType != null){ srvDef.autobuild = true srvDef.builder = null}else srvDef.autobuild = falsereturnthis}override This withAlias(Str alias){ srvDef.aliases = [alias]returnthis}override This withAliases(Str[]? aliases){ srvDef.aliases = aliasesreturnthis}override This withAliasType(Type aliasType){ srvDef.aliasTypes = [aliasType]returnthis}override This withAliasTypes(Type[]? aliasTypes){ srvDef.aliasTypes = aliasTypesreturnthis}override This withScope(Str scope){ withScopes([scope])}override This withScopes(Str[]? serviceScopes){if(serviceScopes != null && srvDef.moduleId != IocModule# && serviceScopes.any {it.equalsIgnoreCase("builtIn")})throw IocErr(ErrMsgs.serviceBuilder_scopeReserved(srvDef.id ?: "", "builtIn")) srvDef.declaredScopes = toImmutableObj(serviceScopes)returnthis}override This withRootScope(){ withScopes(["root"])}// override This addScope(Str scope) {// if (srvDef.moduleId != IocModule#.qname && scope.equalsIgnoreCase("builtIn"))// throw IocErr(ErrMsgs.serviceBuilder_scopeReserved(srvDef.id ?: "", "builtIn"))//// srvDef.declaredScopes = toImmutableObj((srvDef.declaredScopes ?: Str[,]).rw.add(scope))// return this// }override This withBuilder(|Scope -> Obj?|? serviceBuilder){ srvDef.builder = toImmutableObj(serviceBuilder)if(serviceBuilder != null){ srvDef.autobuild = false srvDef.implType = null}else srvDef.autobuild = truereturnthis}** Passed as args to the service ctor. The args must be immutable.override This withCtorArgs(Obj?[]? args){ srvDef.ctorArgs = toImmutableObj(args)if(args != null)// if null, we may not be autobuilding srvDef.autobuild = truereturnthis}** Field values to set in the service impl. An alternative to using ctor args. All vals must be immutable.override This withFieldVals([Field:Obj?]? fieldVals){ srvDef.fieldVals = toImmutableObj(fieldVals)if(fieldVals != null)// if null, we may not be autobuilding srvDef.autobuild = truereturnthis}privatestatic Obj? toImmutableObj(Obj? obj){if(obj is Func)return Env.cur.runtime == "js" ? obj : obj.toImmutablereturn obj?.toImmutable}}