【发布时间】:2017-03-24 14:14:50
【问题描述】:
我正在寻找使用 autofac 解决 Captive Dependency 问题的最简洁方法。
我有一个短期课程,将根据 LifeTimeScope 注册:
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() 所以我不必为我发出的每个请求实例化新的 HttpClients。 ShortLived 类是 IOwinContext,它注册在 Owin Pipeline 的 LifeTimeScope 中。
我可以在 autofac 中注册 HttpConfiguration,而不是 currentLifeTimeScope 的静态变量。然后我可以使用 httpConfig.DependencyResolver.GetRequestLifetimeScope(); 获得 currentLifeTimeScope我还没有测试过这种方法。我仍然希望找到更干净的东西。
【问题讨论】: