mbierlee / poodinis Goto Github PK
View Code? Open in Web Editor NEWDependency injection framework for D with support for autowiring.
License: MIT License
Dependency injection framework for D with support for autowiring.
License: MIT License
If I want to run some code after all dependencies injected.
Is the constructor injection the only way to do so?
The following code does not compile:
import poodinis;
struct MyStruct
{
}
class MyClass
{
@Value("")
MyStruct myStruct;
}
void main()
{
auto dependencies = new shared DependencyContainer();
dependencies.register!(ValueInjector!MyStruct, MyStructInjector);
dependencies.register!(MyClass);
}
class MyStructInjector : ValueInjector!MyStruct
{
MyStruct get(string key)
{
return MyStruct();
}
}
Here are the error messages:
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/container.d-mixin-397(397,24): Error: undefined identifier app.MyStruct
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/container.d(321,24): Error: template instance poodinis.container.DependencyContainer.callPostConstructors!(ValueInjector!(MyStruct)) error instantiating
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/container.d(265,54): instantiated from here: resolve!(ValueInjector!(MyStruct), ValueInjector!(MyStruct))
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/autowire.d(214,28): instantiated from here: resolve!(ValueInjector!(MyStruct))
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/autowire.d(138,49): instantiated from here: injectValue!("myStruct", 0LU, "", false, MyClass)
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/autowire.d(118,3): ... (3 instantiations, -v to show) ...
../../.dub/packages/poodinis-8.0.0/poodinis/source/poodinis/container.d(146,47): instantiated from here: register!(MyClass, MyClass)
source/app.d(18,17): instantiated from here: register!(MyClass)
dmd failed with exit code 1.
In case you register an interface with a class and you forgot to add the interface to the class definition,
there is an error message:
sample2.d(23,18): Error: template poodinis.container.DependencyContainer.register does not match any template declaration
Execute with dub sample2
/+ dub.sdl:
name "sample2"
dependency "poodinis" version="8.0.3"
+/
import std;
import poodinis;
interface IfFileSystem
{
string readTextFile(string filePath);
}
class FileSystem
{
string readTextFile(string filePath) {return readText(filePath);}
}
class DefaultApplicationContext : ApplicationContext
{
public override void registerDependencies(shared(DependencyContainer) container)
{
container.register!(IfFileSystem, FileSystem);
}
}
void main()
{
auto dc = new shared DependencyContainer();
dc.registerContext!DefaultApplicationContext;
}
It's so sad that the Hunt-Framework has broken with Poodinis 8.1.0-beta.3.
When you see this message, we have forced it to use Poodinis 8.1.0-beta.2.
Here are the errors:
hunt-framework 3.4.0-beta.3+commit.21.g7877f83: building configuration "library"...
../../poodinis/source/poodinis/container.d(414,28): Error: template instance `std.traits.isFunction!(BaseObject, Object)` does not match template declaration `isFunction(X...)`
with `X = (hunt.pool.BaseObject.BaseObject, object.Object)`
must satisfy the following constraint:
` X.length == 1`
../../poodinis/source/poodinis/container.d(331,33): Error: template instance `poodinis.container.DependencyContainer.callPostConstructors!(RedisPoolConfig)` error instantiating
../../poodinis/source/poodinis/container.d(275,60): instantiated from here: `resolve!(RedisPoolConfig, RedisPoolConfig)`
../../poodinis/source/poodinis/factory.d-mixin-162(163,80): instantiated from here: `resolve!(RedisPoolConfig)`
../../poodinis/source/poodinis/container.d(183,36): instantiated from here: `ConstructorInjectingInstanceFactory!(RedisPool)`
../../poodinis/source/poodinis/container.d(314,59): ... (1 instantiations, -v to show) ...
../../poodinis/source/poodinis/container.d(275,60): instantiated from here: `resolve!(RedisPool, RedisPool)`
../../hunt-framework/source/hunt/framework/application/Application.d(509,60): instantiated from here: `resolve!(RedisPool)`
../../poodinis/source/poodinis/autowire.d(273,28): Error: template instance `std.traits.isFunction!(BaseObject, Object)` does not match template declaration `isFunction(X...)`
with `X = (hunt.pool.BaseObject.BaseObject, object.Object)`
must satisfy the following constraint:
` X.length == 1`
../../poodinis/source/poodinis/container.d(184,36): Error: template instance `poodinis.autowire.AutowiredRegistration!(RedisPoolConfig)` error instantiating
The container.register
is the problem.
After using initializedBy
, most of registrations passed except for the hunt.framework.view.View
.
../../poodinis/source/poodinis/autowire.d-mixin-273(273,1): Error: no property `TemplateLexer` for type `hunt.framework.view.Environment.Environment`
../../poodinis/source/poodinis/container.d(184,36): Error: template instance `poodinis.autowire.AutowiredRegistration!(Environment)` error instantiating
../../poodinis/source/poodinis/container.d(148,53): instantiated from here: `register!(Environment, Environment)`
../../hunt-framework/source/hunt/framework/provider/ViewServiceProvider.d(23,18): instantiated from here: `register!(Environment)`
../../poodinis/source/poodinis/container.d-mixin-414(414,1): Error: no property `TemplateLexer` for type `hunt.framework.view.Environment.Environment`
../../poodinis/source/poodinis/container.d(331,33): Error: template instance `poodinis.container.DependencyContainer.callPostConstructors!(Environment)` error instantiating
../../poodinis/source/poodinis/container.d(275,60): instantiated from here: `resolve!(Environment, Environment)`
../../poodinis/source/poodinis/factory.d-mixin-162(163,79): instantiated from here: `resolve!(Environment)`
../../poodinis/source/poodinis/container.d(183,36): instantiated from here: `ConstructorInjectingInstanceFactory!(View)`
../../poodinis/source/poodinis/container.d(148,53): instantiated from here: `register!(View, View)`
../../hunt-framework/source/hunt/framework/provider/ViewServiceProvider.d(25,18): instantiated from here: `register!(View)`
To check this, run them please:
git clone https://github.com/huntlabs/hunt-skeleton.git myproject
cd myproject
dub run
since this commit I can no longer build projects with ldc due to:
../../../.dub/packages/poodinis-6.0.0/source/poodinis/autowire.d(124): Error: template instance hasUDA!(__traits(getMember, instance, member), AssignNewInstance) template 'hasUDA' is not defined
Although this is probably a ldc problem it may be worth changinf the travis build to use multiple compilers so that these kind of problem can be detected prior to doing a release. Put the following into .travis.yml
:
d:
- dmd
- dmd-2.069.2
- dmd-2.068.2
- ldc
- gdc
Hello.
The error occurs when using template types. Need to replace the "container.resolve!" ~ param.stringof
in factory file by "container.resolve!(" ~ param.stringof ~ ")"
.
This coding fails:
> dub sample.d
/+ dub.sdl:
name "sample"
dependency "poodinis" version="8.0.3"
+/
import std;
import poodinis;
interface IfFileSystem
{
string readTextFile(string filePath);
}
class FileSystem : IfFileSystem
{
string readTextFile(string filePath) {return readText(filePath);}
}
class DefaultApplicationContext : ApplicationContext
{
@Component
public IfFileSystem fileSystem()
{
return new FileSystem();
}
}
void main()
{
auto dc = new shared DependencyContainer();
dc.registerContext!DefaultApplicationContext;
auto fs1 = dc.resolve!IfFileSystem;
auto fs2= dc.resolve!FileSystem;
}
Error
Error: cannot implicitly convert expression typeid(IfFileSystem) of type object.TypeInfo_Interface to object.TypeInfo_Class
If I change the ApplicationContext class to:
class DefaultApplicationContext : ApplicationContext
{
@Component
public FileSystem fileSystem()
{
return new FileSystem();
}
}
This will work auto fs2= dc.resolve!FileSystem;
.
For auto fs1 = dc.resolve!IfFileSystem;
an exception is thrown.
It this the expected behavior here?
Classes that are resolved show the following deprecation warning when they have overloads. This happens for any class with overloads, such as:
class ClassWithOverloads
{
public int lala()
{
return 42;
}
public int lala(int valla)
{
return valla;
}
}
The following warning is shown:
Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `lala`
the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from
This is due to the deprecation added in https://dlang.org/changelog/2.102.0.html#dmd.deprecate-getAttributes-overloadSet
Originally posted by vnayar November 3, 2023
For context, when autowiring an instance that has already been pre-defined, the system avoids @Autowire
for values that have already been set. This is very useful when adding fake components during testing.
This is seen in the test here:
poodinis/test/poodinis/containertest.d
Line 148 in 87c036d
However, the same behavior is not seen for members that have the @Value
annotation. Those values get re-initialized. Thus, if you have an autowired component, such as "MyAppConfig" or something like that with many @Value
properties, and then I try to inject an existing instance in a test, e.g. container.register!MyAppConfig.existingInstance(testConfig);
, when the rest of the code tries to resolve that dependency, the @Value
annotations will be processed again, and replace any values set for the test.
Is this a bug, or is it intended behavior with a known workaround? Can you disable re-evaluation of @Value
annotations for existing instances that have been plugged into the DependencyContainer
?
Dmd 2.068.0 introduces a 'hasUDA' function for checking if members have certain UDAs. Make use of this function to reduce clutter in that part of the code (autowiring).
Is there any plan to introduce some way of initialising an instance after it has been fully resolved before it is returned to the user? Like the PostConstruct annotation or InitializingBean in Spring
It appears that when initializing a DependencyContainer
via an ApplicationContext
, a @Component
method (which is used to initialize objects with more complicated setup), does not work when using interface-based injection.
Consider the following snippet:
interface DataSource { }
class ConnectionPoolDataSourceImpl : DataSource { }
class AdminContext : ApplicationContext {
override
void registerDependencies(shared(DependencyContainer) container) {
// This is the workaround to fix this problem.
// container.register!(DataSource, ConnectionPoolDataSourceImpl)
// .existingInstance(getDataSource());
}
// Ideally we would annotate this with "@Component", however, Poodinis does not
// currently allow this to be done with interface-based injection.
// The workaround is to return a concrete type and use it with the commented out code above:
// public ConnectionPoolDataSourceImpl getDataSource() {
@Component
public DataSource getDataSource() {
return new ConnectionPoolDataSourceImpl();
}
}
void main() {
auto container = new shared DependencyContainer();
scope (exit) container.clearAllRegistrations();
container.registerContext!AdminContext;
}
../../../.dub/packages/poodinis-8.1.2/poodinis/source/poodinis/container.d(189,39): Error: cannot implicitly convert expression `typeid(DataSource)` of type `object.TypeInfo_Interface` to `object.TypeInfo_Class`
Is this a bug, working as intended, or something that has not yet been implemented?
Low-priority enhancement.
It's mildly annoying but slightly safer to require all types the container supports to be registered somehow. At the moment, the API requires you to call DependencyContainer.getInstance.register!type
for each type.
It would be nicer to have an @AutoRegister
attribute. When the container attempts to build a type (either from a direct call from user code to resolve
or when processing an @Autowire
attribute), if the type has not explicitly been registered, if it has an @AutoRegister
attribute, the type is registered automatically.
An alternative possibility is providing a mixin to register the enclosing type. I have employed this in my code. However, this doesn't work quite so well when you are attempting to resolve types inside a module constructor or a type's static constructor -- specifically, if the types are in the current module, the success or failure of the resolve
calls depends on the order of declaration. This would be a minor thing, but vibe.d recommends putting your application startup code in a shared module constructor.
I want to define a static @Property DependencyContainer, but failed.
Is there any way to do that? I can get this using Aedi (https://github.com/aermicioi/aedi).
Test code:
import poodinis;
//auto dependencies = new shared DependencyContainer(); // It's OK
final class TestContext
{
/** It doesn't work! */
@property static DependencyContainer dependencies()
{
if(m_dependencies is null)
m_dependencies = new DependencyContainer();
return m_dependencies;
}
private static DependencyContainer m_dependencies;
}
class Driver {}
int main()
{
auto dependencies = TestContext.dependencies;
dependencies.register!Driver; // Error: cannot resolve type for dependencies.register!(Driver)
return 0;
}
Instances which are lazily created in single instance scoped registrations are not initializes thread-safe. D2.067 will have a library function for doing this, see:
http://dlang.org/phobos-prerelease/std_concurrency.html#.initOnce
Consider using this function instead
Currently this shows as a problem in tests but will show for all application contexts which have private members. This issue is introduced in DMD 2.071.0, see "Import access checks for fully qualified names were fixed". This might cause a regression error in the future and break user code. This issue has been filed on the Dlang issue tracker.
Alternatives should be sought out in case this deprecation will turn into effect and the issue in DMD is not yet resolved.
The documentation and examples for DependencyContainer
all show it to be used as a shared object. However, it is not clear in the documentation for resolve or register whether objects that are returned are also shared, and whether they need to make synchronized protections for their methods.
Could it be clarified whether resolved objects (especially those registered using the default option singleInstance
) are thread-local or shared in the documentation?
hello again. Do you have any plans to introduce Springs @Value
annotation? I'm currently using properd to handle my database properties before registering all my dependencies to the DependencyContainer.
It would be a little nicer though if poodinis could do the following:
@Value("db.domain:localhost") // find a property named db.domain or default to localhost
string dbHost;
@Value("db.port") // find a property named db.port or null
int dbPort;
I've updated to the latest Poodinis version and found everything ok except this one thing:
SessionFactoryImpl sessionFactory = methodThatCreatesSessionFactory();
container.register!(SessionFactory, SessionFactoryImpl)(RegistrationOption.doNotAddConcreteTypeRegistration).existingInstance(sessionFactory);
The compiler errors with:
../../../.dub/packages/poodinis-7.0.0/poodinis/source/poodinis/factory.d-mixin-131(133,69): Error: undefined identifier 'EntityMetaData'
../../../.dub/packages/poodinis-7.0.0/poodinis/source/poodinis/factory.d-mixin-131(133,102): Error: undefined identifier 'Dialect'
../../../.dub/packages/poodinis-7.0.0/poodinis/source/poodinis/factory.d-mixin-131(133,128): Error: undefined identifier 'DataSource'
../../../.dub/packages/poodinis-7.0.0/poodinis/source/poodinis/container.d(150,30): Error: template instance poodinis.factory.ConstructorInjectingInstanceFactory!(SessionFactoryImpl) error instantiating
source/config/context.d(28,18): instantiated from here: register!(SessionFactory, SessionFactoryImpl)
the EntityMetaData, Dialect, and DataSource objects are all from Hibernated and are used to create my SessionFactory instance. Once that has been done I have no need to use them anymore so don't want to add them to the container.
class ExampleClassA {}
class ExampleClassB {
@autowire
private ExampleClassA dependency;
}
auto dependencies = new shared DependencyContainer();
dependencies.register!ExampleClassA;
auto exampleInstance = new ExampleClassB();
dependencies.autowire(exampleInstance);
assert(exampleInstance.dependency !is null);
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\autowire.d-mixin-271(271,37): Error: no property 'ExampleClassA' for type 'void'
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\autowire.d-mixin-271(271,37): Error: no property 'ExampleClassA' for type 'void'
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\autowire.d-mixin-271(271,37): Error: no property 'ExampleClassA' for type 'void'
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\autowire.d-mixin-271(271,37): Error: no property 'ExampleClassA' for type 'void'
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\autowire.d-mixin-271(271,37): Error: no property 'ExampleClassA' for type 'void'
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\autowire.d-mixin-271(271,37): Error: no property 'ExampleClassA' for type 'void'
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\container.d(180,30): Error: template instance poodinis.autowire.AutowiredRegistration!(ExampleClassA) error instantiating
......\AppData\Roaming\dub\packages\poodinis-8.0.0\poodinis\source\poodinis\container.d(146,47): instantiated from here: register!(ExampleClassA, ExampleClassA)
......: instantiated from here: register!(ExampleClassA)
class LeClass {
import std.stdio;
}
Will produce the following compiler warning: Deprecation: LeClass.std is not visible from module poodinis.autowire
This is due to a bug in DMD regarding the "allMembers" trait also including imports for some reason.
If this deprecation goes into effect, a workaround must be implemented (such as filtering members named std
and core
).
This happens in release mode.
Compiler: DMD32 D Compiler v2.072.2
OS: Win10 x64
Test: example\quickstart\app.d
I'm working on a webapp that uses poodinis and hibernated and would like to register hibernated's SessionFactory:
auto container = DependencyContainer.getInstance();
container.register!(SessionFactory, SessionFactoryImpl);
however, the SessionFactoryImpl constructor takes 3 args, is it possible to pass them in somehow? I had tried the following but poodinis doesn't like it:
SessionFactory sf = new SessionFactoryImpl(mySchema, mysqlDialect, myDatasource);
auto container = DependencyContainer.getInstance();
container.register!(SessionFactory, sf);
if this isn't possible now, can it be done as a new feature. Please provide an example of how to integrate with hibernated.
just a small issue. while updating to the new 6.1.0 release I was reading about RegistrationOption.DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION
changing to RegistrationOptions.doNotAddConcreteTypeRegistration
. It states RegistrationOptions but it should just be RegistrationOption.
Thanks for the new version btw. I'm already making use of ApplicationContext
to keep all my dependency stuff seperate from my code. Quick question though. Is it possible to use @Component
with a method that takes args?
I'd like to do something like the following:
class PoodinisContext : ApplicationContext {
public override void registerDependencies(shared(DependencyContainer) container) {
auto properties = readProperties("./app.properties");
configureDatabase(properties);
container.register!(SomeDao, SomeDaoImpl);
container.register!(ServiceLayer, ServiceLayerImpl);
container.register!(SomeService, SomeServiceImpl);
}
@Component
SessionFactory configureDatabase(string[string] properties) {
... ALL CODE HERE TO SETUP DB FROM PROPERTIES
return new SessionFactoryImpl(schema, dialect, dataSource);
}
}
or, if that's not doable, to at least use @Component
with a method that takes args that should be in the container:
class PoodinisContext : ApplicationContext {
public override void registerDependencies(shared(DependencyContainer) container) {
container.register!(SomeDao, SomeDaoImpl);
container.register!(ServiceLayer, ServiceLayerImpl);
}
@Component
SomeService configureDatabase(SomeDao dao) {
return new SomeServiceImpl(dao);
}
}
Here is a demo for this bug:
// It's modified from https://github.com/mbierlee/poodinis/blob/develop/example/injectioninitializer/app.d
import poodinis;
import std.stdio;
struct Lexer(string exprOpBegin) {
}
class Environment
{
private { // Bug: one
alias TemplateLexer = Lexer!("");
}
TemplateLexer lexer;
this() {
}
}
interface IDoohickey {
}
class Doohickey : IDoohickey
{
Environment _env;
this(Environment env) {
_env = env;
}
static IDoohickey create() {
return new Doohickey(new Environment());
}
}
void main()
{
auto dependencies = new shared DependencyContainer();
dependencies.register!(IDoohickey, Doohickey).initializedBy({
writeln("Creating Doohickey via initializer delegate.");
// return new Doohickey(new Environment()); // OK
return Doohickey.create();
// Bug: two
// It's fixed in PR https://github.com/mbierlee/poodinis/pull/34.
});
dependencies.resolve!Doohickey;
}
As a developer I want to have the option of specifying a context as a string when registering dependencies so that I can register multiple interface implementations or subclasses without having to autowire any classes.
Using a context, all classes can be kept loosely coupled from Poodinis at all times. Also, the developer can structure the dependency tree in one place rather than having to modify classes to specify autowire attributes.
Associate the field
Registration[][TypeInfo] registrations
inside the class DependencyContainer
with a context string, ie:
Registration[][TypeInfo][string] registrations
and overload the register method with a string parameter that allows the client to specify a context string parameter. Not specifying a string will result in registering in the "default"
array. Resolving dependencies will first try to resolve within their registered context before reverting to the default context.
Consider the following example:
import poodinis;
struct TestStruct
{
}
class TestStructInjector : ValueInjector!TestStruct
{
TestStruct get(string key)
{
return TestStruct.init;
}
}
class TestClass
{
this(TestStruct testStruct)
{
this.testStruct = testStruct;
}
@Value("") TestStruct testStruct;
}
void main()
{
auto container = new shared DependencyContainer();
container.register!(ValueInjector!TestStruct, TestStructInjector);
container.register!(TestClass);
}
This does not compile:
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(169,39): Error: cannot implicitly convert expression typeid(TestStruct) of type object.TypeInfo_Struct to object.TypeInfo_Class
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(181,36): Error: template instance `AutowiredRegistration!(TestStruct)` does not match template declaration AutowiredRegistration(RegistrationType : Object)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(305,59): Error: template instance `poodinis.container.DependencyContainer.register!(TestStruct, TestStruct)` error instantiating
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(266,60): instantiated from here: resolve!(TestStruct, TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/factory.d-mixin-152(153,63): instantiated from here: resolve!(TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(180,36): instantiated from here: ConstructorInjectingInstanceFactory!(TestClass)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(147,53): instantiated from here: register!(TestClass, TestClass)
source/app.d(29,11): instantiated from here: register!(TestClass)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(333,68): Error: cannot cast expression registration.getInstance(new AutowireInstantiationContext) of type object.Object to TestStruct
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(338,68): Error: cannot cast expression registration.getInstance(autowireContext) of type object.Object to TestStruct
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(321,41): Error: template instance `poodinis.container.DependencyContainer.resolveAutowiredInstance!(TestStruct)` error instantiating
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(266,60): instantiated from here: resolve!(TestStruct, TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/factory.d-mixin-152(153,63): instantiated from here: resolve!(TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(180,36): instantiated from here: ConstructorInjectingInstanceFactory!(TestClass)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(147,53): instantiated from here: register!(TestClass, TestClass)
source/app.d(29,11): instantiated from here: register!(TestClass)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(312,24): Error: cannot implicitly convert expression null of type typeof(null) to TestStruct
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/factory.d(163,44): Error: no property create for type object.TypeInfo_Struct
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(180,36): Error: template instance `poodinis.factory.ConstructorInjectingInstanceFactory!(TestStruct)` error instantiating
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(305,59): instantiated from here: register!(TestStruct, TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(266,60): instantiated from here: resolve!(TestStruct, TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/factory.d-mixin-152(153,63): instantiated from here: resolve!(TestStruct)
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(180,36): ... (1 instantiations, -v to show) ...
../../.dub/packages/poodinis-8.0.2/poodinis/source/poodinis/container.d(147,53): instantiated from here: register!(TestClass, TestClass)
source/app.d(29,11): instantiated from here: register!(TestClass)
/usr/bin/dmd failed with exit code 1.
It works correctly when using basic types (e.g. int
) instead of TestStruct
and it also works correctly when removing the constructor in TestClass
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.