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.88k stars 163 forks source link

Consider the open-generic API #600

Open hadashiA opened 8 months ago

hadashiA commented 8 months ago

In #367, open generic registers were merged. First of all, I accept the PR proposal as is, but there are some points I would like to reconsider.

mixedHans commented 5 months ago

I have a problem with resolving multiple implementations of an open generic interface through resolving an IReadOnlyList of this interface. But the list is empty. Do i miss something or do the resolving wrong?

public interface IOpenGenericInterface<T1, T2> { }
public class Implementation<T1, T2> : IOpenGenericInterface<T1, T2> { }
public class AnotherImplementation<T1, T2> : IOpenGenericInterface<T1, T2> { }

public class MyLifetimeScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        builder.Register(typeof(Implementation<,>), Lifetime.Transient)
            .As(typeof(IOpenGenericInterface<,>));

        builder.Register(typeof(AnotherImplementation<,>), Lifetime.Transient)
            .As(typeof(IOpenGenericInterface<,>));

        builder.Register<Usage>(Lifetime.Scoped)
            .AsSelf();

        builder.RegisterBuildCallback(resolver => resolver.Resolve<Usage>());
    }
}

public class Usage
{
    private readonly IObjectResolver m_ObjectResolver;

    public Usage(IObjectResolver objectResolver)
    {
        m_ObjectResolver = objectResolver;
        MyMethod<int, int>();
    }

    void MyMethod<T1, T2>()
    {
        var openGenericInterfaces = m_ObjectResolver.Resolve<IReadOnlyList<IOpenGenericInterface<T1, T2>>>();
        Debug.Log(openGenericInterfaces.Count); // 0
        foreach (var openGenericInterface in (IEnumerable)openGenericInterfaces)
        {
            // Do something
        }
    }
}