WinForms使用Autofac跨项目RegisterAssemblyTypes注册服务失效咨询
Autofac 批量注册服务故障解决方案
首先可以明确:完全可以通过RegisterAssemblyTypes实现服务的自动批量注册,不需要手动编写数十行注册代码。
问题根源
你的批量注册代码的核心错误是Where过滤条件写反了:
t.Name.StartsWith("I")会筛选出所有名称以I开头的类型,也就是IUserData、IWarehouseData这类接口本身,而你需要注册的是UserData、WarehouseData这类接口的实现类,注册接口类型本身没有任何实际作用,所以无法正常解析服务。
正确的批量注册写法
根据你的命名规则(实现类名 = 接口名去掉首字母I),可以用以下代码实现精准批量注册:
static Autofac.IContainer RootContainerFixed() { ContainerBuilder builder = new(); builder.RegisterType<ZFApplication>().SingleInstance(); builder.RegisterType<ZFBundle>().SingleInstance(); // 推荐用程序集内的已知类型加载程序集,避免Assembly.Load的加载上下文问题 var targetAssembly = Assembly.GetAssembly(typeof(IUserData)); builder.RegisterAssemblyTypes(targetAssembly) // 过滤条件:只保留非接口、非抽象的具体实现类 .Where(t => !t.IsInterface && !t.IsAbstract // 可选:增加规则校验,只注册符合「接口名=I+类名」命名规范的服务,避免误注册其他无关类 && t.GetInterfaces().Any(i => i.Name == $"I{t.Name}")) // 注册为自身实现的所有接口 .AsImplementedInterfaces(); return builder.Build(); }
额外注意事项
- 如果你的实现类是
internal访问级别,需要在ZFDataLib.ModelAndInterface项目的AssemblyInfo.cs中添加以下配置,允许Autofac访问内部类型:
或者在注册代码中添加[assembly: InternalsVisibleTo("Autofac")]PublicOnly(false)配置,允许注册非公开类型:builder.RegisterAssemblyTypes(targetAssembly).PublicOnly(false) - 可以根据业务需要在
AsImplementedInterfaces()后追加生命周期配置,比如SingleInstance()(单例)、InstancePerLifetimeScope()(作用域单例)等,默认是瞬时生命周期。
内容的提问来源于stack exchange,提问作者Chandra Arifin
相关产品推荐
相关产品推荐

