【问题标题】:Unity configured with PerRequestLifetimeManager() creating multiple instances of DbContext per request for WebApi requests, but not MVC requests使用 PerRequestLifetimeManager() 配置的 Unity 为 WebApi 请求的每个请求创建多个 DbContext 实例,但不是 MVC 请求
【发布时间】:2019-10-20 04:03:47
【问题描述】:

这是我的UnityConfig.cs

public class UnityConfig
{
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        RegisterTypes(container);
        return container;
    });

    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<IProjectContext, ProjectContext>(new PerRequestLifetimeManager());
    }
}

这是我的UnityWebApiActivator.cs

public static class UnityWebApiActivator
{
    public static void Start()
    {
        Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));

        var container = UnityConfig.GetConfiguredContainer();
        var resolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }

    public static void Shutdown()
    {
        var container = UnityConfig.GetConfiguredContainer();
        container.Dispose();
    }
}

单步执行代码,我可以看到使用适当的注册创建了我的容器。

这是一个示例 WebAPI 控制器:

[Authorize]
public class ProjectApiController : BaseApiController
{
    private readonly ProjectService _projectService;

    public ProjectApiController(ProjectService projectService)
    {
        _projectService = projectService;
    }

    [Route("api/project")]
    [AcceptVerbs("POST")]
    public HttpResponseMessage SendProject(ProjectDto projectDto)
    {
        return Request.CreateResponse(HttpStatusCode.OK, _projectService.SendProject(GetUsername(), projectDto));
    }
}

虽然我的 ProjectService 构造函数看起来像这样:

public class ProjectService : BaseService
{

    public readonly ProjectContext _db;
    public readonly NotificationService _notificationService;

    public ProjectService(ProjectContext db, NotificationService notificationService)
    {
        _db = db;
        _notificationService = notificationService;
    }
    // methods here
 }

MVC 控制器和 API 控制器都依赖于 ProjectService,但 WebAPI 请求的行为不同。提供 MVC 请求时,我会根据需要创建一个 ProjectContext 实例。当提供 WebAPI 请求时,每次注入都会创建一个新实例。这是不希望的。

为什么会这样?

更新:

根据below answer,我已经改变了

DependencyResolver.SetResolver(new UnityDependencyResolver(container));

DependencyResolver.SetResolver(new UnityHierarchicalDependencyResolver(container));

这导致:

类型 Microsoft.Practices.Unity.WebApi.UnityHierarchicalDependencyResolver 似乎没有实施 Microsoft.Practices.ServiceLocation.IServiceLocator。参数名称: commonServiceLocator

这导致我here,推荐的解决方案导致:

我目前有:

  • Unity 4.0.1
  • Unity.AspNet.WebApi 4.0.1
  • Unity.Mvc 4.0.1
  • Unity.MVC5 1.2.3

升级包是目前的最后手段。

【问题讨论】:

    标签: c# .net asp.net-mvc asp.net-web-api unity-container


    【解决方案1】:

    我们在 net core 2.2 应用程序中的 dbContext (EF Core) 以及 SimpleInjector 库中遇到了类似的问题。无论我们提供什么生命周期值,都没有正确设置 dbContext 生命周期。最糟糕的是,故障是间歇性的,因此更难解决。

    我们发现我们注册了 dbContext 两次,一次是在 netcore 的 DI 容器中,第二次是在 SimpleInjector 容器中,这会导致各种问题。

    因此,我建议您检查您是否还注册了两次。仅供参考,如果是这种情况,那么建议删除它们,因为设置相同的生命周期值对我们不起作用。

    【讨论】:

      猜你喜欢
      • 2015-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-04
      • 2018-05-22
      • 2017-05-02
      • 1970-01-01
      • 2010-11-07
      相关资源
      最近更新 更多