.NET MVC+Identity+EF项目使用Unity实现依赖注入配置咨询
实现步骤说明
1. 注册范围说明
你需要同时注册DbContext和所有自定义服务,不需要强制创建接口:接口属于可选优化项,主要用于单元测试时替换模拟实现,如果你暂时没有测试需求,可以直接注册实现类。
2. 改造UnityConfig配置
首先修改你的UnityConfig类,按如下方式注册组件,注意DbContext使用请求级生命周期,保证每个请求共用同一个DbContext,符合EF的使用规范:
public static class UnityConfig { public static void RegisterComponents() { var container = new UnityContainer(); // 注册ApplicationDbContext,生命周期为每个请求一个实例 container.RegisterType<ApplicationDbContext>(new PerRequestLifetimeManager(), new InjectionConstructor("DefaultConnection")); // 注册自定义服务,默认是瞬态生命周期,每次请求创建新实例 container.RegisterType<XxService>(); container.RegisterType<YyService>(); // 如果后续你创建了服务接口,就按下面的方式注册(可选) // container.RegisterType<IXxService, XxService>(); // container.RegisterType<IYyService, YyService>(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); } }
注意:需要在
Global.asax的Application_Start方法里调用UnityConfig.RegisterComponents(),否则配置不会生效。
3. 改造服务层代码
把服务中手动new其他服务的逻辑删掉,改为构造函数注入,Unity会自动完成依赖传递:
public class XxService { private ApplicationDbContext db; private YyService yyService; // 依赖全部通过构造函数注入,不要手动new public XxService(ApplicationDbContext db, YyService yyService) { this.db = db; this.yyService = yyService; } public string Foo(int id) { Customer customer = yyService.Bar(id); return customer.Name; } }
YyService原有构造函数已经符合注入要求,不需要修改。
4. 改造控制器代码
删掉控制器中手动实例化DbContext和服务的逻辑,改为构造函数注入需要的服务即可:
public class SomeController : Controller { private XxService xxService; // 直接注入需要的服务,不需要自己管理DbContext和服务的实例化 public SomeController(XxService xxService) { this.xxService = xxService; } public ActionResult Index() { string name = xxService.Foo(5); return View(); } }
可选:引入接口的规范写法
如果需要做单元测试,建议为每个服务定义对应接口,示例如下:
public interface IXxService { string Foo(int id); } public class XxService : IXxService { // 原有实现保持不变 }
注册时改为:
container.RegisterType<IXxService, XxService>();
控制器注入时改为注入接口:
public SomeController(IXxService xxService) { this.xxService = xxService; }
这样后续测试时可以直接替换为Mock的IXxService实现,不需要修改业务代码。
内容的提问来源于stack exchange,提问作者patsy2k
相关产品推荐
相关产品推荐

