Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

.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 }




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: