.NET's DI has constructor injection so I suppose this is similar; you just write your constructor saying "I need an `IDataProvider`" and it can come from DI or direct.
Question I have for Go though. Without DI, what is the idiomatic way of supplying one of n implementations? An if-else block? Like if I had 5 possible implementations (AzureBlobStore, AwsBlobStore, GcpBlobStore, CFBlobStore, FSBlobStore) and I need to supply 10 dependent services with access to `IBlobStore` what would that code look like?
In .NET, it would look like:
// Resolve the concreteImpl in DI
IBlobStore concreteImpl = switch (config.BlobStoreType) {
case "Azure": new AzureBlobStore();
case "Aws": new AwsBlobStore();
default: new FSBlobStore();
};
// Register
services.AddSingleton<IBlobStore>(concreteImpl)
services.AddScoped<Svc1>();
services.AddScoped<Svc2>();
// Services just use primary constructor and receive impl
public class Svc1(IBlobStore store) { }
public class Svc2(IBlobStore store) { }
// But I can also manually supply (e.g. unit testing)
var mockBlobStore = new MockBlobStore();
var svc2 = new Svc2(mockBlobStore);
Yeah it basically is just an if-else or switch block.
type BlobStore interface { /* methods */ }
// later, when initializing stuff
var foo BlobStore
switch {
case isAzure:
foo = AzureBlobStore{}
default:
foo = FSBlobStore{}
}
svc1 := NewSvc1(foo)
// Constructors are just functions and are totally
// convention/arbitrary. If the fields are public you
// can instantiate the struct directly.
svc2 := Svc2{ BlobStore: foo }
Question I have for Go though. Without DI, what is the idiomatic way of supplying one of n implementations? An if-else block? Like if I had 5 possible implementations (AzureBlobStore, AwsBlobStore, GcpBlobStore, CFBlobStore, FSBlobStore) and I need to supply 10 dependent services with access to `IBlobStore` what would that code look like?
In .NET, it would look like: