digitalmars.D.learn - How to store a pointer to class contructor
- Dmitriy Asondo (17/17) Dec 24 2020 Hi!
- Dmitriy Asondo (4/4) Dec 24 2020 The idea is to store somewhere services (classes) first and only
- Mike Parker (19/23) Dec 24 2020 There's `Object.factory`, which constructs a class instance from
- Dmitriy Asondo (6/29) Dec 24 2020 Hm... So, I need helpers like common interface for services &
- Mike Parker (4/7) Dec 24 2020 At compile time, you'd get it from the type, not the reference:
- Jacob Shtokolov (14/18) Dec 24 2020 Hi, it seems that what you're looking for is Prototype
- Jacob Carlborg (42/49) Dec 25 2020 Here's a slightly different version that I think is closer to
Hi! You may hate me, but currently I'm using nodejs. I want to use dlang as a second instrument and I'm trying to check some js-like features. For example, if I want to store somewhere in array|tuple a list of pointers to classes (app services) how may I do that? I expect code like this: ---------------------- class OloloService {} class BlablaService {} auto servicesList = [OloloService, BlablaService]; auto serviceInstance = new servicesList[1](args); ---------------------- But such costructions is impossible in D, so, may be anybody may explain how to organize app "services" and what ways of dependency injection exist for D? Thank you :)
Dec 24 2020
The idea is to store somewhere services (classes) first and only when the app need - instantiate services for app/thread/http-request (as option) and provide values to constructors via DI
Dec 24 2020
On Thursday, 24 December 2020 at 10:33:00 UTC, Dmitriy Asondo wrote:The idea is to store somewhere services (classes) first and only when the app need - instantiate services for app/thread/http-request (as option) and provide values to constructors via DIThere's `Object.factory`, which constructs a class instance from a fully-qualified name: https://dlang.org/phobos/object.html#.Object.factory But IIRC there are issues with it in some cases and I believe it's supposed to be deprecated at some point. I'd just give the classes an interface and use function pointers to construct them: ``` interface IService { ... } alias ServiceMaker = IService function(); ServiceMaker[string] serviceRegistry; class FooService : IService { ... } IService makeFooService() { return new FooService(); } void registerServices() { serviceRegistry["FooService"] = &makeFooService; } ```
Dec 24 2020
On Thursday, 24 December 2020 at 11:02:11 UTC, Mike Parker wrote:On Thursday, 24 December 2020 at 10:33:00 UTC, Dmitriy Asondo wrote:Hm... So, I need helpers like common interface for services & function-factory for every. It would be difficult to automate) Ok, I see, thank you! Is there any way, for example on compile step, to get class name from class pointer? To automate generation of factory via templateThe idea is to store somewhere services (classes) first and only when the app need - instantiate services for app/thread/http-request (as option) and provide values to constructors via DIThere's `Object.factory`, which constructs a class instance from a fully-qualified name: https://dlang.org/phobos/object.html#.Object.factory But IIRC there are issues with it in some cases and I believe it's supposed to be deprecated at some point. I'd just give the classes an interface and use function pointers to construct them: ``` interface IService { ... } alias ServiceMaker = IService function(); ServiceMaker[string] serviceRegistry; class FooService : IService { ... } IService makeFooService() { return new FooService(); } void registerServices() { serviceRegistry["FooService"] = &makeFooService; } ```
Dec 24 2020
On Thursday, 24 December 2020 at 11:15:28 UTC, Dmitriy Asondo wrote:Is there any way, for example on compile step, to get class name from class pointer? To automate generation of factory via templateAt compile time, you'd get it from the type, not the reference: typeid(T).name;
Dec 24 2020
On Thursday, 24 December 2020 at 10:23:09 UTC, Dmitriy Asondo wrote:Hi! I'm trying to check some js-like features. For example, if I want to store somewhere in array|tuple a list of pointers to classes (app services) how may I do that?Hi, it seems that what you're looking for is Prototype Inheritance, which is not quite common among staticly typed programming languages due to its runtime nature. Please note that the way you've implemented it in JavaScript doesn't take compile-time class constructors into consideration. Just look at how you're passing constructor parameters to your objects. In D, each class may have its own constructor, so the arguments may be totally different. Also, it looks like you're trying to implement some kind of a Service Locator. Could you tell what are you trying to achieve with this code? Are the arguments and the array index received at runtime?
Dec 24 2020
On Thursday, 24 December 2020 at 10:23:09 UTC, Dmitriy Asondo wrote:I expect code like this: ---------------------- class OloloService {} class BlablaService {} auto servicesList = [OloloService, BlablaService]; auto serviceInstance = new servicesList[1](args); ----------------------Here's a slightly different version that I think is closer to your original example: import std; interface Service {} mixin template Constructor() { this(int a) { } } class OloloService : Service { mixin Constructor; } class BlablaService : Service { mixin Constructor; } Service function(int) create(T)() { return a => new T(a); } void main() { auto servicesList = [create!OloloService, create!BlablaService]; auto serviceInstance = servicesList[1](3); writeln(serviceInstance); } Since D is a statically typed language you need a form of base type if you want to store a list of values of different types. In this case, the base type is `Service`. If you want to have a constructor, as you do in your original example, the constructor needs to have the same signature for all types, the mixin template helps with that. You can use a tuple as well to store different values of different types. But then everything need to be known at compile time. That is, the index, in your case. -- /Jacob Carlborg
Dec 25 2020