7

Autofac IoC kapsayıcısını kullanarak InstancePerHttpRequest ömür boyu kapsamını sağlayan MVC4 eklentisini kullanıyorum. Ancak benim projemde web, web-api ve arka plan çalışan iş parçacığı var. Aşağıdaki örnekte, InstancePerHttpRequest kapsamının bir web isteğinden kaynaklanmadığı zaman çok fazla olamayacağını varsayıyorum.Birden fazla Autofac yaşam boyu kapsamları bir kayıtta belirtilebilir mi?

builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>() 
    .InstancePerHttpRequest() 

Ben BT aşağıdaki gibi bir şey yapmak ve konteyner en uygun yaşam boyu kapsamını seçmek zorunda mümkün olup olmadığını merak ediyorum? istek o InstancePerApiRequest kapsamını seçecek bir WebAPI isteği kaynaklanıyorsa o zaman InstancePerHttpRequest kapsamını seçecektir bir web isteğinden kaynaklanır eğer gerçekleşmesi niyetinde ne Bu durumda

builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>() 
    .InstancePerHttpRequest() 
    .InstancePerApiRequest() 
    .InstancePerDependency(); 

olup, kullanıldığı takdirde uygulama çalışan iş parçacığı tarafından InstancePerDependency kapsamını kullanacak?

Bu ya da benzer bir şey mümkün olduğunda herhangi bir fikir var mı?
Teşekkür

cevap

10

Bu soru bu bazı oldukça ağır bir örtüşme vardır:

Sen bu kontrol etmek isteyeceksinizbazı fikirler için.

Kısa cevap şu: Bu tür bir kutu kutudan desteklenmiyor. Birkaç şeyden birini yapmanız gerekir.

Seçenek: Arka plan konuları için farklı bir kapsayıcı olabilir. Bu, uygulama düzeyinde singletonları paylaşmanıza izin vermez, ancak uygulamanız için sorun olabilir.

Seçenek: Kaptan iki ömür boyu kapsam oluşturabilir ve aramanın bir parçası olarak BeginLifetimeScope numaralı telefonun farklı kayıtlarını yapabilirsiniz. Bu, uygulama düzeyinde singletonları paylaşmanıza ve farklı bağlamlarda aynı bileşenler için farklı ömür boyu kapsamlara sahip olmanızı sağlar. Ancak, kayıtları yönetmek biraz daha zordur ve her mantıksal bağlamın kendi kapsamından çözülmesi gerektiğinden iki farklı servis bulucuya (örneğin, DependencyResolver) ihtiyacınız olacaktır.

var builder = new ContainerBuilder(); 
builder.RegisterType<AppLevelSingleton>().SingleInstance(); 
var container = builder.Build(); 

// Create a nested lifetime scope for your background threads 
// that registers things as InstancePerDependency, etc. Pass 
// that scope to whatever handles dependency resolution on the thread. 
var backgroundScope = container.BeginLifetimeScope(
    b => b.RegisterType<DatabaseFactory>() 
     .As<IDatabaseFactory>() 
     .InstancePerDependency()); 

// Create a nested lifetime scope for the web app that registers 
// things as InstancePerHttpRequest, etc. Pass that scope 
// as the basis for the MVC dependency resolver. 
var webScope = container.BeginLifetimeScope(
    b => b.RegisterType<DatabaseFactory>() 
     .As<IDatabaseFactory>() 
     .InstancePerHttpRequest()); 
var resolver = new AutofacDependencyResolver(webScope); 
DependencyResolver.SetResolver(resolver); 

Gerçekten bu seçenekle fantezi olsun istedim, bunu öyle ve uygun iç içe kapsamından şeyler giderir hangi bağlam algılayabilen bir özel IContainer uygulayabilir. Multitenant Autofac desteği bu şekilde çalışır. Ancak, bu çok daha karmaşık bir çözümdür, bu yüzden hepsini buraya yazmayacağım. Örnekler için multitenant desteği için Autofac kaynağını kontrol edin.

Seçenek: Sen InstancePerDependency veya InstancePerLifetimeScope gibi kayıt bir "düşük ortak payda" tür kullanmak ve uygulamanın farklı bölümleri için farklı bir ömür boyu sahip kavramını atlamak olabilir.Şu anda, teknik olarak, içten, InstancePerHttpRequest ve InstancePerWebApiRequest ne arasında hiçbir fark yoktur

Not. Her ikisi de aynı şeylere kadar kaynar ve etkili bir şekilde değiştirilebilirler. (Her zaman sonsuza kadar böyle olacağına söz veremem, ama neden değişmesi gerektiğini bilmiyorum.)

+0

Harika! Tam cevap için teşekkür ederiz, bu büyük ölçüde yardımcı olur. – chriskopec

+0

bunun yararlı olacağını düşünün. Bir örnek, dbcontext web api eyleminden beri EF framework kullanıyor, eğer yeni bir iş parçacığıyla veritabanına erişmesi gereken sınıfı çağırıyorsa, olasılıklar sadece instanceperhttprequest ise, istisna atar, bu yüzden InstancePerLifetimeScope'a sahip olma esnekliğine sahip olmanız gerekir. InstancePerLifetimeScope'a sahip olmak neredeyse daha iyidir. – koo9

İlgili konular