如果您安装 Unity.Mvc* 和 Unity.WebAPI* Nuget 包并将其添加到您的项目,那么为 ASP.NET MVC 和 WebAPI 设置 Unity 非常容易。 (* 是版本号,例如 3、4 或 5。为您的项目寻找合适的版本。例如链接 to the Unity.Mvc 5 package 和 to the Untity.WebAPI 5 package。)
this blog post 中解释了这些包的用法。
构建块大致是这样的:
您构建一个统一容器并在其中注册所有依赖项,尤其是 EF 上下文:
private static IUnityContainer BuildContainer()
{
var container = new UnityContainer();
container.RegisterType<MyContext>(new HierarchicalLifetimeManager());
container.RegisterType<IOrderService, OrderService>();
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IEmailMessenger, EmailMessenger>();
// etc., etc.
return container;
}
MyContext 是您的派生 DbContext 类。使用HierarchicalLifetimeManager 注册上下文非常重要,因为它将确保每个 Web 请求的新上下文将在每个请求结束时由容器实例化和释放。
如果您的服务没有接口而只有具体的类,您可以删除上面注册接口的行。如果需要将服务注入控制器,Unity 只会创建具体服务类的实例。
一旦你构建了容器,你就可以在Application_Startglobal.asax中将它注册为MVC和WebAPI的依赖解析器:
protected void Application_Start()
{
var container = ...BuildContainer();
// MVC
DependencyResolver.SetResolver(
new Unity.MvcX.UnityDependencyResolver(container));
// WebAPI
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApiX.UnityDependencyResolver(container);
}
一旦设置了DependencyResolvers,如果参数可以用注册的类型解析,框架就能够实例化在其构造函数中接受参数的控制器。例如,您现在可以创建一个CustomerController,然后注入一个CustomerService 和一个EmailMessenger:
public class CustomerController : Controller
{
private readonly ICustomerService _customerService;
private readonly IEmailMessenger _emailMessenger;
public CustomerController(
ICustomerService customerService,
IEmailMessenger emailMessenger)
{
_customerService = customerService;
_emailMessenger = emailMessenger;
}
// now you can interact with _customerService and _emailMessenger
// in your controller actions
}
这同样适用于 WebAPI 的派生 ApiControllers。
服务可以依赖上下文实例与实体框架交互,如下所示:
public class CustomerService // : ICustomerService
{
private readonly MyContext _myContext;
public CustomerService(MyContext myContext)
{
_myContext = myContext;
}
// now you can interact with _myContext in your service methods
}
当 MVC/WebAPI 框架实例化一个控制器时,它将注入注册的服务实例并解析它们自己的依赖关系,即将注册的上下文注入服务构造函数。您将注入控制器的所有服务都将在单个请求期间收到相同的上下文实例。
使用此设置,您通常不需要context = new MyContext() 或context.Dispose(),因为 IOC 容器将管理上下文生命周期。