Unity настроен с помощью PerRequestLifetimeManager (), создающего несколько экземпляров DbContext для запроса на запросы WebApi, но не на запросы MVC - PullRequest
2 голосов
/ 20 октября 2019

Вот мой 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 обслуживается, каждая инъекция создает новый экземпляр. Это нежелательно.

Почему это происходит?

Обновление:

Согласно ответу ниже , я изменился

DependencyResolver.SetResolver(new UnityDependencyResolver(container));

до

DependencyResolver.SetResolver(new UnityHierarchicalDependencyResolver(container));

Это привело к:

Тип Microsoft.Practices.Unity.WebApi.UnityHierarchicalDependencyResolver, по-видимому, не реализует Microsoft. Practices.ServiceLocation.IServiceLocator. Имя параметра: commonServiceLocator

Что привело меня сюда , где рекомендуемое решение приводит к:

enter image description here

У меня сейчас есть:

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

Обновление пакетов в крайнем случае прямо сейчас.

1 Ответ

0 голосов
/ 29 октября 2019

У нас была похожая проблема с нашим dbContext (EF Core) в приложении net core 2.2 вместе с библиотекой SimpleInjector. Время жизни dbContext не было установлено должным образом, независимо от того, какое значение времени жизни мы предоставили. Хуже всего было то, что сбой был прерывистым, что делало его еще сложнее выяснить.

Мы обнаружили, что регистрируем dbContext дважды, один раз в контейнере DI netcore и второй раз в контейнере SimpleInjector, который вызывал все виды. из вопросов.

Следовательно, я бы рекомендовал проверить, если вы также регистрируете его дважды. Просто к вашему сведению, если это так, то рекомендую избавиться от одного из них, так как установка одинаковых значений времени жизни у нас не работает.

...