2017-02-18 88 views
0

Я новичок в Autofac и имею следующие регистрации компонентов StructureMap, которые я хотел бы перевести, но я обеспокоен тем, что моя реализация может быть выполнена не по назначению. Autofac уделяет большое внимание тому факту, что вы не должны разрешаться вне сферы жизни (т. Е. Container.Resolve), но, конечно, container.BeginLifetimeScope() недоступен до тех пор, пока не будет создан ContainerBuilder.Перевести StructureMap-компонент на версию Autofac

For<ISessionSource>().Singleton().Use<NHibernateSessionSource>(); 

For<ISession>().Use(ctx => { 
    var unitOfWork = (INHibernateUnitOfWork)ctx.GetInstance<IUnitOfWork>(); 
    return unitOfWork.Session; 
});    

For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use<NHibernateUnitOfWork>(); 

Autofac:

builder.RegisterType<NHibernateSessionSource>().As<ISessionSource>().SingleInstance(); 

// Is the following recommended? Define that whenever request an `ISession` it should return the `Session` property of the concrete implementation of `INHibernateUnitOfWork`: 
builder.Register(ctx => 
{ 
    var unitOfWork = (INHibernateUnitOfWork)ctx.Resolve<IUnitOfWork>(); 
    return unitOfWork.Session; 
}).As<ISession>().InstancePerRequest(); 

builder.RegisterType<NHibernateUnitOfWork>().As<IUnitOfWork>().InstancePerRequest(); 
+1

Я не уверен, что у меня возникли проблемы. Реализация выглядит хорошо для меня, и ** очень ** близко к StructureMap. Не могли бы вы подробнее рассказать? –

+0

Да, это очень близко к StructureMap (хотя я улучшил его с моей первой начальной реализации, поскольку я написал вопрос, как это часто бывает ;-). Моя проблема заключается в том, что Autofac не советует не разрешать услуги непосредственно из корневого контейнера, а скорее из вложенных LifetimeScopes. Однако вы не можете сделать это до создания контейнера. Я абсолютно уверен, что это правильная реализация, но я совершенно не знаком с Autofac, поэтому хочу, чтобы у вас не было ничего (например, способ сделать что-то вроде container.BeginLifetimeScope до создания контейнера). – Ted

+0

«Хотя можно разрешать компоненты прямо из корневого контейнера, выполнение этого через ваше приложение в некоторых случаях может привести к утечке памяти. Рекомендуется всегда разрешать компоненты из области жизни, где это возможно, чтобы убедиться, что экземпляры службы правильно собранных и собранных мусора ». – Ted

ответ

0

Вот что мы вышли из комментариев.

ОП обеспокоен тем, что ctx в лямбда представляет собой контейнер для корней, и в результате считалось, что эти регистрации не придерживаются лучших практик, поскольку Autofac - как и любой другой контейнер IoC - советует не разрешать услуги из корневого контейнера ,

Получается, что на самом деле ctx представляет контекст текущего разрешения во время выполнения лямбда.

Использование InstancePerRequest в регистрационных точках указывает на то, что ctx будет в данном случае областью видимости контекста HTTP-запроса.

В целом, текущая регистрация Autofac выглядит хорошо и похожа на StructureMap.