digitalmars.D.learn - class Object with Dependency Injection
- Salih Dincer (77/77) Jun 18 2023 Hi, below is an example of DI-dependency injection with 3
- =?UTF-8?Q?Ali_=c3=87ehreli?= (14/17) Jun 18 2023 The problem is with the deduced type of 'services'. I don't know the
- Salih Dincer (25/31) Jun 18 2023 This is very interesting because it looks like a bug. Why is
Hi, below is an example of DI-dependency injection with 3 versions nested in the code. If you remove the leading // characters, you will not get the "no property `deliver` for `service` of type `object.Object`" error. Because version-2I with interface wants its methods to depend on Object.. ```d //abstract class /* toggle-code interface //* ^---version 2A */ ITransport { string deliver(); } class Ship : ITransport { override string deliver() { return "Ship Deliver"; } } class Truck : ITransport { override string deliver() { return "Truck Deliver"; } } abstract class Logistics { ITransport createTransport(); auto operations() { return createTransport.deliver(); } } class RoadLogistics : Logistics { override ITransport createTransport() { return new Truck(); } } class SeaLogistics : Logistics { override ITransport createTransport() { return new Ship(); } } import std.stdio; void main() { // DI version 1: auto sl = new SeaLogistics; auto rl = new RoadLogistics; auto logistics = [ sl, rl ]; foreach(deliver; logistics) { auto str = deliver.operations(); str.length.writeln(": ", str); } import std.range : repeat; "÷ ".repeat(9).writefln!"%-(%s%)"; // A->I version 2: auto truck = new Truck; auto ship = new Ship; auto services = [ truck, ship ]; foreach(service; services) { auto str = service.deliver(); str.length.writeln(": ", str); } } ``` Maybe using an abstract class instead of interface or not using auto will solve the problem, but I can't accept the situation! I wonder what makes the interface special? SDB 79
Jun 18 2023
On 6/18/23 07:37, Salih Dincer wrote:auto truck = new Truck; auto ship = new Ship; auto services = [ truck, ship ];The problem is with the deduced type of 'services'. I don't know the mechanism behind it but the common type of 'truck' and 'ship' are deduced to be Object. Apparently, their interfaces don't take part in that decision. I don't know why. One solution is to help the compiler by casting them to your desired interface: auto services = [ cast(ITransport)truck, cast(ITransport)ship ]; Or you can put the casts inside a function that could hide the complexity below: import std.algorithm; import std.range; auto services = [ truck, ship ].map!(s => cast(ITransport)s).array; Ali
Jun 18 2023
On Sunday, 18 June 2023 at 16:58:15 UTC, Ali Çehreli wrote:The problem is with the deduced type of 'services'. I don't know the mechanism behind it but the common type of 'truck' and 'ship' are deduced to be Object. Apparently, their interfaces don't take part in that decision. I don't know why.This is very interesting because it looks like a bug. Why is there no problem in an abstracted object, but things get confused in the interface (ITransport)? On Sunday, 18 June 2023 at 16:58:15 UTC, Ali Çehreli wrote:One solution is to help the compiler by casting them to your desired interface:In fact, there is no need to cast: ```d interface ITransport { string deliver(); } //... void main() { auto truck = new Truck; ITransport ship = new Ship; /* or ITransport truck = new Truck; auto ship = new Ship; // or ITransport truck = new Truck; ITransport ship = new Ship;//*/ } ``` SDB 78
Jun 18 2023