MVC 3, Unity 2 - менеджер запросов времени жизни по запросу - PullRequest
2 голосов
/ 15 июня 2011

Я использую код Unity MVC3 на http://unitymvc3.codeplex.com/, чтобы иметь сеанс NHibernate для каждого экземпляра запроса IUnitOfWork.

Он работал несколько недель назад, я внес некоторые изменения, и теперь у моего IUnitOfWork, похоже, статическое время жизни.

Из моего global.asax.cs:

private static IUnitOfWorkFactory _UoWFactory = new UnitOfWorkFactory(Enums.Databases.MyDBName)
                                                            .AddMapping<DepartmentMap>()
                                                            .CompleteConfiguration();

/// <summary>
/// Configure Unity Application Block
/// </summary>
private void ConfigureUnity()
{
    CIUnity.UnityContainer.Container = new UnityContainer()
        .RegisterType(typeof(IRepository<>), typeof(Repository<>))
        .RegisterType<IUnitOfWork, UnitOfWork>(Enums.Databases.MyDBName.ToString(), new HierarchicalLifetimeManager(), new InjectionConstructor(Enums.Databases.MyDBName))
        .RegisterInstance<IUnitOfWorkFactory>(Enums.Databases.MyDBName.ToString(), _UoWFactory);

    DependencyResolver.SetResolver(new UnityDependencyResolver(CIUnity.UnityContainer.Container));
}

ConfigureUnity() вызывается из моего Application_Start()

Вот мой тестовый код из моего конструктора HomeController:

private IUnitOfWork uow;
private IUnitOfWork uow2;

public HomeController()
{
    uow = CIUnity.Container.Resolve<IUnitOfWork>(Enums.Databases.MyDBName.ToString());
    IRepository<Employee> repo = uow.GetRepository<Employee>();

    uow2 = CIUnity.Container.Resolve<IUnitOfWork>(Enums.Databases.MyDBName.ToString());
    IRepository<Department> deptrepo = uow2.GetRepository<Department>();

    var q = from a in repo.Find()
            select a;

    var d = from b in deptrepo.Find()
            select b;
}

... IUnitOfWork разрешается в том же экземпляреоднако при последующих запросах страницы новый IUnitOfWork не создается ... но код работает, поэтому он каким-то образом регистрирует / вытягивает объект, чтобы он работал статично.

Ответы [ 2 ]

2 голосов
/ 16 июня 2011

Я бы полностью избавился от IUnitOfWorkFactory и просто внедрил IUnityOfWork в свой контроллер - при условии, что вам когда-нибудь понадобится только одна единица работы на запрос, что кажется логичным.Затем вы больше используете возможности контейнера IoC, а не просто используете его в качестве локатора службы.

Просто измените конструктор HomeController на:

public HomeController(IUnitOfWork unitOfWork)
{
  IRepository<Employee> repo = unitOfWork.GetRepository<Employee>();

  IRepository<Department> deptrepo = unitOfWork.GetRepository<Department>();

  ...
}

И если вы еще этого не сделалипоэтому добавьте:

CIUnity.Container.RegisterControllers();

перед вызовом DependencyResolver.SetResolver

Когда ядро ​​MVC пытается создать экземпляр вашего контроллера, оно будет использовать распознаватель Unity.MVC3, который автоматически удовлетворяет любые зависимости, которыев этом случае означает unitOfWork.

Резолвер Unity.MVC3 также автоматически позаботится об утилизации вашей единицы работы в конце запроса.

0 голосов
/ 16 июня 2011

Похоже, вы хотите, чтобы UnitOfWorkFactory возвращал ваши зависимости IUnitOfWork?Похоже, вы должны использовать .RegisterFactory для достижения этой цели.Вы можете зарегистрировать фабрику с помощью ContainerControlledLifetimeManager, и она будет вести себя как «одиночка», не прибегая к статическому члену.

Управление жизненным циклом может быть немного сложнее с WCF (и, вероятно, с сетью).Я давно пользуюсь кодом из этой статьи.Он отлично отображает время жизни Unity и время жизни запроса WCF ... Это может дать вам некоторые идеи о том, как наилучшим образом достичь вашей цели.

http://drewdotnet.blogspot.com/2009/07/unity-lifetime-managers-and-wcf.html

...