2017-02-18 42 views
0

我是Autotac的新手,並且我想要翻譯下列StructureMap組件註冊,但擔心我的實現可能不會按照推薦的方式完成。 Autofac提出的事實,你不應該一輩子範圍(即container.Resolve)之外解決高度重視,當然,直到ContainerBuildercontainer.BeginLifetimeScope()不可用。將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

下面是我們從發了評論。

的OP擔心ctx在lambda代表的根容器,並因此認爲,這些註冊沒有堅持,因爲Autofac最佳實踐 - 像任何其他IoC容器 - 從根容器建議不要解析服務。

事實證明,實際上,ctx表示lambda執行時的當前分辨率上下文。

在註冊中使用InstancePerRequest指向事實ctx在這種情況下將是HTTP請求生存期範圍上下文。

總而言之,目前的Autofac註冊看起來不錯,類似於StructureMap。