autofac / Autofac

An addictive .NET IoC container
https://autofac.org
MIT License
4.44k stars 836 forks source link

Implement "WhenInjectInto" like others IoC - Feature request #1387

Closed avechuche closed 12 months ago

avechuche commented 12 months ago

Hello, I do not know if there is a functionality for this (I think not because I did not find anything similar on the internet) but I think it would be useful for Autofac

Problem Statement

I want to use an interface (MyInterface) in 2 or more implementations but I want one of those implementations to inject that interface (MyInterface) with a particular implementation. It looks like a tongue twister

Desired Solution

public class MyRepositoryProxyCache : IMyRepository
{
    private readonly ICacheProvider<MyClass> _cacheProvider;

    private readonly IMyRepository _myRepository;

    public MyRepositoryProxyCache(ICacheProvider<MyClass> cacheProvider, IMyRepository myRepository)
    {
        _cacheProvider = cacheProvider;
        _myRepository = myRepository;
    }

    public Task<MyClass?> GetByIDAsync(int id)
    {
        return _cacheProvider.GetOrSetAsync("CACHE_KEY", () => _myRepository.GetByIDAsync(id));
    }
}

public class MyRepository : IMyRepository
{
    public MyRepository() { }

    public Task<MyClass?> GetByIDAsync(int id)
    {
        return CUSTOM_DB_CALL;
    }
}

public interface IMyRepository
{
    Task<MyClass?> GetByIDAsync(int id);
}

OtherIoC.Export<MyRepository>().As<IMyRepository>().When.InjectedInto<MyRepositoryProxyCache>();
OtherIoC.Export<MyRepositoryProxyCache>().As<IMyRepository>();
tillig commented 12 months ago

There are a lot of other ways to do these sorts of things in Autofac.

I don't think we'll be adding this feature because there are other ways to already do the same thing. We also already have #1203 for specifically supporting a proxy-oriented relationship.

avechuche commented 12 months ago

Thanks for the help, I already have a simple solution. I share it for the next generations.


private static void WhenUseInto<T, TProxy, TImplementation>(ContainerBuilder containerBuilder) where T : TImplementation where TProxy : TImplementation where TImplementation : notnull
{
    containerBuilder
        .RegisterType<T>()
        .Named<TImplementation>(typeof(TImplementation).Name);
    containerBuilder
        .RegisterType<TProxy>()
        .WithParameter(ResolvedParameter.ForNamed<TImplementation>(typeof(TImplementation).Name))
        .As<TImplementation>();
}

WhenUseInto<MyRepository, MyRepositoryProxyCache, IMyRepository>(containerBuilder);