You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Grace/Ninject的WhenInjectInto逻辑迁移至Autofac?

Grace至Autofac依赖注册迁移方案(替代WhenInjectInto)

业务代码实现

public interface ILocationRepository
{
    Task<Location?> GetByIDAsync(int id);
}

public class LocationRepositoryProxyCache : BaseProxyCache, ILocationRepository
{
    private readonly ICacheProvider<Location> _cacheProvider;
    private readonly ILocationRepository _locationRepository;

    public LocationRepositoryProxyCache(ICacheProvider<Location> cacheProvider, ILocationRepository locationRepository)
    {
        _cacheProvider = cacheProvider;
        _locationRepository = locationRepository;
    }

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

public class LocationRepository : BaseRepository<Location>, ILocationRepository
{
    public LocationRepository(IMyInterface myAppDb) : base(myAppDb) { }

    public Task<Location?> GetByIDAsync(int id)
    {
        return ...; // 数据库查询逻辑
    }
}

原Grace注册代码

registrationBlock.Export<LocationRepository>().As<ILocationRepository>().When.InjectedInto<LocationRepositoryProxyCache>();
registrationBlock.Export<LocationRepositoryProxyCache>().As<ILocationRepository>();

Autofac迁移实现

Autofac没有直接的WhenInjectInto方法,但可以通过以下两种方式实现相同逻辑:

方式一:利用注册条件判断目标类型

通过When方法结合解析上下文的TargetType,判断当前注入的目标类型,实现和WhenInjectInto等价的效果:

var builder = new ContainerBuilder();

// 当注入目标是LocationRepositoryProxyCache时,使用真实的LocationRepository
builder.RegisterType<LocationRepository>()
       .As<ILocationRepository>()
       .When(context => context.TargetType == typeof(LocationRepositoryProxyCache));

// 注册缓存代理作为默认的ILocationRepository实现
builder.RegisterType<LocationRepositoryProxyCache>()
       .As<ILocationRepository>();

var container = builder.Build();

方式二:使用命名服务(更明确的依赖指向)

通过命名服务区分真实仓库和代理,避免条件判断的潜在歧义,适合复杂依赖场景:

var builder = new ContainerBuilder();

// 注册真实仓库并指定名称
builder.RegisterType<LocationRepository>()
       .Named<ILocationRepository>("RealLocationRepository");

// 注册缓存代理,构造时明确解析命名的真实仓库
builder.RegisterType<LocationRepositoryProxyCache>()
       .As<ILocationRepository>()
       .WithParameter(
           (parameter, context) => parameter.ParameterType == typeof(ILocationRepository),
           (parameter, context) => context.ResolveNamed<ILocationRepository>("RealLocationRepository")
       );

var container = builder.Build();

效果说明

两种方式均能实现:

  • 当LocationRepositoryProxyCache需要注入ILocationRepository时,获取真实的数据库访问实现LocationRepository
  • 其他依赖ILocationRepository的地方,默认获取带缓存的代理实现LocationRepositoryProxyCache

内容的提问来源于stack exchange,提问作者avechuche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:52:54