Unity 2.0 IOC с Entity Framework - PullRequest
       16

Unity 2.0 IOC с Entity Framework

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

Я использую Unity 2.0 с asp.net mvc3 в моем проекте.Исключение выдается, когда я пытаюсь настроить TestEntities : ObjectContext в своем классе Repository.

public class UserRepository:IUser
{
    //TestEntities ctx = new TestEntities();
    [Dependency]
    public TestEntities ctx { get; set; }
    //...
}

Это сообщение об исключении:

Тип TestEntities имеет несколько конструкторовдлина 1. Невозможно устранить неоднозначность.

Конфигурация XML:

<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="schemas.microsoft.com/practices/2010/unity">
    <container>
        <register type="DomainModel.Entity.TestEntities, DomainModel"
                  mapTo="DomainModel.Entity.TestEntities, DomainModel">
            <lifetime type="perthread"/>
        </register>
        <register type="DomainModel.Abstract.IUser, DomainModel"
                  mapTo="DomainModel.Concrete.UserRepository, DomainModel">
            <lifetime type="perthread"/>
        </register>
    </container>
</unity>

1 Ответ

3 голосов
/ 29 октября 2011

Это совершенно неверная конфигурация.Прежде всего, вы используете время жизни каждого потока.Время жизни для каждого потока предназначено для сценариев, в которых вы сами управляете потоками, но в ASP.NET MVC такого контроля нет.ASP.NET MVC использует внутренний пул потоков, поэтому потоки используются для последующих запросов = ваш контекст будет повторно использоваться в запросах, и это вызовет у вас много проблем .Другая проблема заключается в том, что время жизни для каждого потока не будет обрабатывать удаление контекста, поэтому, если вы сами не справитесь с этим (что довольно сложно, если у вас нет времени жизни под вашим контролем), вашему приложению будет достаточно большой памятиутечки.

Вы должны использовать другое управление временем жизни:

  • Per-resol: Это создаст новый экземпляр каждый раз, когда вы вызываете Resolve для контейнера, но в случае иерархии зависимостей тот же экземплярбудет использоваться для всех инъекций.Вы должны сами справиться с удалением контекста.
  • Переходный процесс: при каждом вызове Resolve будет создаваться новый экземпляр.Если экземпляр требуется более одного раза во время иерархии зависимостей, он будет создавать новый экземпляр для каждого внедрения.Вы должны сами обработать удаление контекста.
  • Иерархический: вы должны создавать новый подконтейнер для каждой обработки запроса и разрешать экземпляр на этом подконтейнере.Один и тот же экземпляр будет использоваться каждый раз, когда вы вызываете Resolve для этого экземпляра подконтейнера.Вы должны утилизировать подконтейнер, как только закончите с запросом, и все экземпляры с иерархическим временем жизни будут также удалены.
  • Пользовательский менеджер времени жизни, такой как этот пример для каждого запроса , но с правильной конфигурацией внедрения зависимостейв этом не должно быть необходимости, и для каждого разрешения или иерархического менеджера должны быть выполнены все ваши требования.

Подробнее о различных менеджерах времени жизни можно прочитать в моей статье .

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

<register type="DomainModel.Entity.TestEntities, DomainModel"
          mapTo="DomainModel.Entity.TestEntities, DomainModel">
    <lifetime type="perresolve"/>
    <constructor />
</register>
...