5

AutoFac wiki sayfası hakkında Circular References kullanmayı diyor ki:Autofac 2.4.5 ile dairesel referanslar nasıl kullanılır?

cb.Register<DependsByProp>().OnActivated(ActivatedHandler.InjectUnsetProperties); 

Ama ActivatedHandler 2.4.5 yılında artık yok gibi görünüyor. Kaynakta etrafta dolaşırken, o sınıfın uygulamasını buldum ve bunun yerine OnActivated'de yöntem uygulamasına girdim. Ne yazık ki, bu hala çalışmıyor.

Burada Wiki sayfasında olana benzeyen minimal bir repro yerleştirdim.

class M 
{ 
    public VM VM { get; set; } 

    public M() 
    { 
    } 
} 

class VM 
{ 
    public VM(M m) 
    { 
    } 
} 

[Fact] 
void CanResolveCircular() 
{ 
    ContainerBuilder builder = new ContainerBuilder(); 

    builder.RegisterType<VM>(); 
    builder.RegisterType<M>().OnActivated(e => e.Context.InjectUnsetProperties(e.Instance)); 

    using (var container = builder.Build()) 
    { 
     var m = container.Resolve<M>(); 
     Assert.NotNull(m); 
    } 
} 

Bu kod, Resolve girişimi başarısız olduğunda yığın taşması istisnası atmaya devam eder. Neyi kaçırıyorum? Dairesel bağımlılıkları ele almak için Autofac'ı edinmenin doğru yolu nedir?

+0

Evet. Dairesel bağımlılıkların örnek döngüleri ile aynı anlama geldiğini düşündüm. Aşağıdaki cevabınız, sınıflar ve örnekler arasındaki dairesel bağımlılık kavramları hakkında eksik olduğumu gösterdi. – Ants

cevap

7

circular dependencies devletler için Autofac belgeleri:

Not, her iki sınıfları Fabrikası kapsamı ile kayıtlı ise bu senaryo kurmak mantıklı değil.

Hem sizin M ve VM kayıtları InstancePerDependency (önceden FactoryScope olarak da bilinir), böylece bu açıklama sizin senaryo için de geçerlidir. Sonuç olarak, M ve VM örneklerini oluşturmada sonsuz bir döngü elde edersiniz. Eğer tesis çözmek aynı örneği M ait almak VM enjekte istiyorsanız

, sen InstancePerDependency (örn SingleInstance) dışında bir M ömrünü değişmelidir. Bu aşağıda gösterilmiştir:

builder.RegisterType<M>().PropertiesAutowired(true).SingleInstance(); 

Not: Ben de daha yeni PropertiesAutowired (true) uzantısı yöntemini kullanıyorum. Bunu, repro'nuzdaki OnActivated kodunun yerine kullanabilirsiniz.

uygulama başına M tek bir örneğini istemiyorsanız, yapabilirsin kurulum bir LifetimeScope ve InstancePerLifetimeScope kullanın. Burada ilgilenen herkes için

5

bunu yapmanın yeni bir yoludur:

class DependsByProp1 
{ 
    public DependsByProp2 Dependency { get; set; } 
} 

class DependsByProp2 
{ 
    public DependsByProp1 Dependency { get; set; } 
} 

// ... 

var cb = new ContainerBuilder(); 
cb.RegisterType<DependsByProp1>() 
     .InstancePerLifetimeScope() 
     .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); 
cb.RegisterType<DependsByProp2>() 
     .InstancePerLifetimeScope() 
     .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); 

Property/Property Dependencies

İlgili konular