我正在尋找最簡潔的方式來解決與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;我還沒有測試過這種方法。我仍然希望找到更乾淨的東西。