Autofac能否像Spring的@Resource一样通过属性注入指定实例?
实现Autofac类似Spring @Resource的按名称注入功能
步骤1:定义自定义ResourceAttribute特性
创建特性类,用于标记需要按名称注入的属性:
[AttributeUsage(AttributeTargets.Property)] public class ResourceAttribute : Attribute { public string Name { get; } public ResourceAttribute(string name) { Name = name; } }
步骤2:修改Autofac注册逻辑
在Autofac Module中,按名称注册服务,并为控制器添加激活时的属性解析逻辑:
public class AutofacModule : Module { protected override void Load(ContainerBuilder builder) { // 按名称注册ITestService的实现类 builder.RegisterType<TestService1>().As<ITestService>().Named<ITestService>("TestService1"); builder.RegisterType<TestService2>().As<ITestService>().Named<ITestService>("TestService2"); // 注册控制器并处理自定义属性注入 builder.RegisterControllers(typeof(Program).Assembly) .PropertiesAutowired() // 开启属性注入 .OnActivating(e => { var instanceType = e.Instance.GetType(); // 遍历实例所有公共属性 foreach (var prop in instanceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var resourceAttr = prop.GetCustomAttribute<ResourceAttribute>(); if (resourceAttr != null && prop.PropertyType.IsInterface) { // 根据特性指定的名称解析服务实例 var serviceInstance = e.Context.ResolveNamed(resourceAttr.Name, prop.PropertyType); prop.SetValue(e.Instance, serviceInstance); } } }); } }
步骤3:在控制器中使用特性指定注入实例
在TestController的属性上标记[Resource]特性,指定要注入的服务名称:
public class TestController : ControllerBase { [Resource("TestService2")] public ITestService TestService { get; set; } [HttpGet] public string Test() { return TestService.Test(); // 此时会返回TestService2的"Test2" } }
关键说明
- 服务注册必须使用
Named<T>方法指定唯一名称,确保Autofac能根据名称定位对应实例。 - 控制器注册时开启
PropertiesAutowired()是基础,保证Autofac处理属性注入;OnActivating事件是自定义逻辑核心,用于识别Resource特性并完成按名称解析。 - 如果需要支持构造函数注入的按名称匹配,可通过自定义
Parameter实现,当前属性注入方式更贴合Spring @Resource的使用习惯。
内容的提问来源于stack exchange,提问作者koishi
相关产品推荐
相关产品推荐

