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

Autofac注册类型为自身及指定接口时无法访问具体类型的解决方法

问题描述

我尝试将程序集类型同时注册为自身及一个指定接口。当添加As<ICustomScreenDef>后,无法再访问具体类型;但使用AsImplementedInterfaces()时,访问具体类型恢复正常。

示例代码:

public class ScreenDef : IScreenDef {}
public class MyScreen : ScreenDef, ICustomScreenDef {}
public class ScreenGroup 
{
   public ScreenGroup(MyScreen myScreen, IEnumerable<ICustomScreenDef> customScreenDefs){}
}

注册代码(Program.cs):

builder.RegisterAssemblyTypes(screensAssembly).AssignableTo<IScreenDef>().
    OnActivating(e => {
        IScreenDef screenDef = ((IScreenDef)e.Instance);
        screenDef.Init();
    })     
    .OnActivated(
        e => {
            ...
        }
    ).AsSelf().As<ICustomScreenDef>().InstancePerDependency();

使用上述代码时,ScreenGroup无法实例化,因为缺少myScreen依赖;若将AsSelf().As<ICustomScreenDef>()改为AsSelf().AsImplementedInterfaces()则运行正常。请问如何不使用AsImplementedInterfaces()实现需求?

解决方案

问题出在Autofac的注册逻辑上:当链式调用AsSelf()后再调用As<ICustomScreenDef>(),你没有显式注册IScreenDef服务,同时Autofac的As方法会调整可解析的服务列表,导致MyScreen自身类型的注册未被正确关联。

要解决这个问题,有两种可行方式:

方式一:一次性指定所有服务类型

使用As()的lambda重载,一次性传入所有需要注册的服务类型(自身、ICustomScreenDef、IScreenDef):

builder.RegisterAssemblyTypes(screensAssembly)
    .AssignableTo<IScreenDef>()
    .OnActivating(e => {
        var screenDef = (IScreenDef)e.Instance;
        screenDef.Init();
    })
    .OnActivated(e => {
        ...
    })
    .As(t => new[] { t, typeof(ICustomScreenDef), typeof(IScreenDef) })
    .InstancePerDependency();

方式二:显式逐个注册所有服务

依次调用AsSelf()、As<IScreenDef>和As<ICustomScreenDef>,确保所有需要的服务类型都被注册:

builder.RegisterAssemblyTypes(screensAssembly)
    .AssignableTo<IScreenDef>()
    .OnActivating(e => {
        var screenDef = (IScreenDef)e.Instance;
        screenDef.Init();
    })
    .OnActivated(e => {
        ...
    })
    .AsSelf()
    .As<IScreenDef>()
    .As<ICustomScreenDef>()
    .InstancePerDependency();

原代码失效原因

原注册代码只指定了AsSelf()和As<ICustomScreenDef>,但没有显式注册IScreenDef——而你的筛选条件是AssignableTo<IScreenDef>,但该接口并未被加入服务列表。AsImplementedInterfaces()会自动注册所有实现的接口(包括IScreenDef和ICustomScreenDef),同时保留自身类型的注册,所以能正常解析MyScreen和IEnumerable<ICustomScreenDef>。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:00:04