Веб-API + Unity — объект ссылки dbcontext уже создан

Я использую Unity для внедрения зависимостей.

У меня есть метод, ответственный за создание экземпляра объекта базы данных, следующим образом:

        container.RegisterType<DB>(
            new InjectionFactory(c =>
            {
                return new DB();
            })
        );

Проблема в том, что у меня есть метод, который использует два разных объекта, которые должны ссылаться на один и тот же экземпляр БД, но похоже, что Unity создает новый экземпляр объекта БД при каждой инъекции.

Пример запроса LINQ:

var test = from tb1 in _db1.method()
           join tb2 in _db2.method() on tb1.code equals tb2.code

_db1 и _db2 ссылаются на один и тот же объект БД, как показано ниже.

    DB _db = null;

    public db1(DB dataContext)
    {
        _db = dataContext;
        _db.CommandTimeout = 3600;
    }

Итак, я получаю следующую ошибку:

Запрос содержит ссылки на элементы, определенные в другом контексте данных.

Может ли кто-нибудь помочь мне исправить регистр Unity, чтобы ссылаться на уже созданный объект БД, вместо того, чтобы каждый раз делать новый?


person MarceloBarbosa    schedule 12.11.2015    source источник


Ответы (1)


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

container.RegisterType<DB>(new ContainerControlledLifetimeManager())

следует сделать это, если это веб-приложение, вам, вероятно, следует создать дочерний контейнер для каждого запроса. Существуют разные способы сделать это, но вы можете указать https://www.nuget.org/packages/Unity.Mvc4/ попробуйте

person Robbert Draaisma    schedule 12.11.2015
comment
Теперь, когда я регистрирую зависимость, я использую следующий код: container.RegisterType<IAdminDB, AdminDB>(new HierarchicalLifetimeManager()); HierarchicalLifetimeManager() следует заменить на ContainerControlledLifetimeManager()? - person MarceloBarbosa; 12.11.2015
comment
Делая, как вы сказали, я начал получать эту ошибку: An error occurred when trying to create a controller of type 'ExampleController'. Make sure that the controller has a parameterless public constructor.". Я без идей. - person MarceloBarbosa; 12.11.2015
comment
@MarceloBarbosa, вы регистрируете ExampleController в контейнере? Можете показать, как выглядит конструктор ExampleController? Можете ли вы показать, как вы используете контейнер для разрешения объектов? Вы используете IDependencyResolver или IHttpControllerActivator? - person Yacoub Massad; 13.11.2015
comment
по умолчанию единство использует TransientLifetimeManager, поэтому каждый раз, когда делается запрос на экземпляр, создается новый. HierarchicalLifetimeManager и ContainerControlledLifetimeManager создают только один экземпляр типа запроса и повторно используют его. Разница между последними важна, когда вы используете дочерние контейнеры. ContainerControlledLifetimeManager позаботится о том, чтобы все дочерние контейнеры использовали один и тот же экземпляр, а с HierarchicalLifetimeManager экземпляр уникален для каждого дочернего контейнера. - person Robbert Draaisma; 13.11.2015
comment
Что касается исключения вашего контроллера, я думаю, что это отдельная проблема, и похоже, что вы неправильно подключили свой контейнер к конвейеру mvc, а преобразователь mvc по умолчанию не любит конструкторы с аргументами. - person Robbert Draaisma; 13.11.2015
comment
Я исправил проблему, используя этот код: container.RegisterType<DB>(new HierarchicalLifetimeManager(), new InjectionFactory(c => { return new DB(); })); Thanks @RobbertDraaisma - person MarceloBarbosa; 13.11.2015