hadashiA / VContainer

The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.
https://vcontainer.hadashikick.jp
MIT License
1.89k stars 165 forks source link

How To Manage Multi Instance? #581

Closed MUDV587 closed 9 months ago

MUDV587 commented 9 months ago

I Have a config class A,it is filled with different data,So I Have 2 Instance a1 a2, How Can I inject a1 to class B, a2 to class C?

AlonTalmi commented 9 months ago

You'll have to be more specific

MUDV587 commented 9 months ago

It is something like this

public class Config
{

}

public class A
{
    readonly Config config;

    public A(Config config)
    {
        this.config = config;
    }
}

public class B
{
    readonly Config config;

    public B(Config config)
    {
        this.config = config;
    }
}

protected override void Configure(IContainerBuilder builder)
{
    base.Configure(builder);

    var configA = new Config();
    var configB = new Config();

    // TODO: I need configA inject to A, and configB inject to B

    builder.Register<A>(Lifetime.Singleton);
    builder.Register<B>(Lifetime.Singleton);
}
AlonTalmi commented 9 months ago

You should look online for dependency injection examples, they're the same for every library.

The general idea is you should've also registered Config and not instantiate it manually and the DI library detects A & B depend on Config.

MUDV587 commented 9 months ago

Maybe my description gave you some misunderstandings

protected override void Configure(IContainerBuilder builder) { base.Configure(builder);

builder.Register<Config>(xxx); // need something to indicate that this one will inject to A
builder.Register<Config>(xxx); // need something to indicate that this one will inject to B
builder.Register<A>(Lifetime.Singleton);
builder.Register<B>(Lifetime.Singleton);

}

What I mean is that A and B need different Config instances. At the same time, I can obtain configA or configB in the subsequent process to make different settings for different situations.

AlonTalmi commented 9 months ago

If you mark the config binding as Transient, a different config instance will be created for each resolve: builder.Register(Lifetime.Transient);

https://vcontainer.hadashikick.jp/scoping/lifetime-overview

hadashiA commented 9 months ago

DI is based on type-keyed static wiring. It's hard to resolve all granular data values with DI. Your Config is more of a data, not a functionality. So my recommendation is to DI a provider that has access to the configuration information.

class A 
{
    public A(ConfigProvider config)
    {
          this.config = config.GetFor("A");
    }
}

And so on.

Alternatively, I suppose you could use the manual wiring to temporarily use a Config instance.

builder.Register(container =>
{
    return new A(config);
}, Lifetime.Singleton);