如何在Unity IoC容器中注入属性?Asp.Net MVC5配置疑难
解决Unity.Mvc5中属性注入失效的问题
咱们一步步排查问题,属性注入失败通常是配置或使用方式的细节没做好,先从几个关键环节入手:
1. 先确认Unity.Mvc5包的安装
别用普通的Unity容器包,一定要通过NuGet安装Unity.Mvc5——这个包专门整合了ASP.NET MVC的控制器激活机制,要是用错包,控制器根本不会由Unity创建,注入自然失效。
2. 正确配置Unity容器(核心步骤)
在App_Start下新建或修改UnityConfig.cs,完成容器初始化、依赖注册和MVC控制器工厂替换:
using Microsoft.Practices.Unity; using System.Web.Mvc; using Unity.Mvc5; using Project2; // 你的Project2.dll的命名空间 public static class UnityConfig { public static void RegisterComponents() { var container = new UnityContainer(); // 第一步:注册你要注入的服务类型和实现类 // 比如你要注入的IService和它的具体实现 container.RegisterType<IService, ConcreteServiceImpl>(); container.RegisterType<IAnotherService, AnotherConcreteServiceImpl>(); // 方式一:用InjectionProperty配置属性注入(不需要加[Dependency]特性) container.Configure<InjectedMembers>() .ConfigureInjectionFor<YourTargetClassInProject2>( new InjectionProperty("FirstInjectedProperty"), new InjectionProperty("SecondInjectedProperty") ); // 方式二:如果用[Dependency]特性,上面的ConfigureInjectionFor可以省略,但要确保特性引用正确 // 关键:把Unity设置为MVC的默认控制器解析器 DependencyResolver.SetResolver(new UnityDependencyResolver(container)); } }
然后在Global.asax.cs的Application_Start里调用注册方法:
UnityConfig.RegisterComponents();
3. 确保目标类的属性符合要求
- 属性必须是public的,Unity无法注入私有/保护属性
- 属性的类型必须是你已经在容器中注册过的服务类型(比如用
IService而不是具体实现类ConcreteServiceImpl,除非你注册了具体类) - 如果用
[Dependency]特性,要确保是Microsoft.Practices.Unity.DependencyAttribute,别引错其他库的同名特性
示例类写法:
using Microsoft.Practices.Unity; namespace Project2 { public class YourTargetClass { // 用[Dependency]特性的写法 [Dependency] public IService FirstInjectedProperty { get; set; } [Dependency] public IAnotherService SecondInjectedProperty { get; set; } // 如果用InjectionProperty配置,就不需要加[Dependency] // public IService FirstInjectedProperty { get; set; } // public IAnotherService SecondInjectedProperty { get; set; } } }
4. 必须让Unity创建目标类的实例
这是最容易踩的坑!如果你自己用new YourTargetClass()手动实例化对象,Unity根本没机会处理属性注入。必须通过Unity容器获取实例:
// 在控制器里的正确用法 public class HomeController : Controller { public ActionResult Index() { // 从Unity容器解析实例 var targetInstance = DependencyResolver.Current.GetService<YourTargetClass>(); // 这里targetInstance的属性应该已经被注入了 return View(); } } // 如果是在非控制器类里,同样要通过容器获取 var targetInstance = DependencyResolver.Current.GetService<YourTargetClass>();
要是你已经手动new了对象,也可以用BuildUp补做注入:
var instance = new YourTargetClass(); container.BuildUp(instance); // 手动触发属性注入
5. 排查其他可能的冲突
- 检查是否有其他IoC容器的配置,可能覆盖了Unity的控制器工厂
- 目标类不能是静态类,Unity无法给静态属性注入
- 确认所有依赖的服务都已经在容器中注册,没有遗漏
最后再走一遍验证流程
- 确认安装了
Unity.Mvc5包 - 容器配置中注册了所有需要注入的服务
- 目标类的属性是public且类型已注册
- 目标类的实例由Unity创建(Resolve/BuildUp)
Global.asax中正确调用了Unity注册方法
内容的提问来源于stack exchange,提问作者Junior
相关产品推荐
相关产品推荐

