2017-03-24 49 views
1

我正在尋找最簡潔的方式來解決與autofac的圈養相關性問題。與Autofac的圈養依賴

我將在每一個LifeTimeScope被registerd一個短命類:

public class ShortLived 
{ 
    public void DoSomethingUsefull() {} 
} 

而且我有一個將被註冊爲單個實例長期居住類。它依賴於ShortLived類:

public class LongLived 
{ 
    private readonly Func<ShortLived> _getCurrentShortLived; 

    public LongLived(Func<ShortLived> getCurrentShortLived) 
    { 
     _getCurrentShortLived = getCurrentShortLived; 
    } 

    public void DoSomethingWithShortLived() 
    { 
     var currentShortLived = _getCurrentShortLived(); 
     currentShortLived.DoSomethingUsefull(); 
    } 
} 

以下嘗試不起作用。它引發一個Autofac.Core.DependencyResolutionException。

public void CaptiveDependencyTest() 
{ 
    var builder = new ContainerBuilder(); 
    builder.RegisterType<LongLived>() 
     .SingleInstance(); 
    var container = builder.Build(); 

    using (var scope = container.BeginLifetimeScope(b => b.RegisterType<ShortLived>())) 
    { 
     var longLived = scope.Resolve<LongLived>(); 
     longLived.DoSomethingWithShortLived(); 
    } 
} 

下面的工作。但我真的希望有一個比依靠某種靜態變量更好的解決方案。

private static ILifetimeScope currentLifetimeScope; 

public void CaptiveDependencyTest2() 
{ 
    var builder = new ContainerBuilder(); 
    builder.Register(c => 
    { 
     Func<ShortLived> shortLivedFacotry =() => currentLifetimeScope.Resolve<ShortLived>(); 
     return new LongLived(shortLivedFacotry); 
    }) 
    .SingleInstance(); 
    var container = builder.Build(); 

    using (var scope = container.BeginLifetimeScope(b => b.RegisterType<ShortLived>())) 
    { 
     currentLifetimeScope = scope; 
     var longLived = scope.Resolve<LongLived>(); 
     longLived.DoSomethingWithShortLived(); 
    } 
} 

一些底色的相關信息: 我工作的OWIN託管ASP.Net WebApi2微服務。在調用其他服務時,我需要讀取currentOwinContext.Request.User.Identity中的值,並將它們添加到發送給下一個服務的RequestMessage中。我的LongLived類是DelegatingHandler(即HttpClient「HttpMessageHandler-Pipeline」的一部分),而HttpClient需要是.SingleInstance(),所以我不必爲每個請求實例化新的HttpClient。 ShortLived類是IOwinContext,它在Owin管道的LifeTimeScope中註冊。

而不是一個currentLifeTimeScope的靜態變量,我可以在autofac中註冊HttpConfiguration。然後我可以通過httpConfig.DependencyResolver.GetRequestLifetimeScope()獲取currentLifeTimeScope;我還沒有測試過這種方法。我仍然希望找到更乾淨的東西。

回答

1

如果類型T與容器的註冊,Autofac會自動解決的Func鍵依賴關係,通過容器創建牛逼實例工廠請找有關委託工廠的詳細信息

註冊您的短命類,如下就是它所有的工作現在好了。

public void CaptiveDependencyTest() 
{ 
    var builder = new ContainerBuilder(); 
    builder.RegisterType<ShortLived>() 
     .SingleInstance(); 
    builder.RegisterType<LongLived>() 
     .SingleInstance(); 
    var container = builder.Build(); 

    //using (var scope = container.BeginLifetimeScope(b => b.RegisterType<ShortLived>())) 
    //{ 
     var longLived = container.Resolve<LongLived>(); 
     longLived.DoSomethingWithShortLived(); 
    //} 
} 

,您可以直接使用,不再需要容器,但最後選擇解決以及是你