Autofac的强制依赖性

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (39)

我正在寻找用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();
    }
}

一些Backround Infos:我正在开发一个OWIN托管的ASP.Net WebApi2微服务。当调用其他服务时,我需要从currentOwinContext.Request.User.Identity中读取值并将它们添加到我发送给下一个服务的RequestMessage中。我的LongLived类是DelegatingHandler(即HttpClient“HttpMessageHandler-Pipeline”的一部分),HttpClient需要是.SingleInstance(),因此我不必为每个请求实例化新的HttpClients。ShortLived类是IOwinContext,它在Owin管道中的LifeTimeScope中注册。

我可以在autofac中注册HttpConfiguration,而不是currentLifeTimeScope的静态变量。然后我可以使用httpConfig.DependencyResolver.GetRequestLifetimeScope()获取currentLifeTimeScope; 我还没有测试过这种方法。我仍然希望找到更清洁的东西。

提问于
用户回答回答于

ASP.NET Core中HttpContext该类提供了该属性public IServiceProvider RequestServices { get; set; }。即使您只引用了根生存期范围,也可以使用此方法解析请求生存期范围中的依赖关系。诀窍是要记住ILifetimeScope可以从任何解决IComponentContext。此行为可以封装在以下扩展方法中。

public static ILifetimeScope GetLifetimeScope(this HttpContext httpContext)
{
   return httpContext.RequestServices.GetService(typeof(ILifetimeScope)) as ILifetimeScope;
}

现在,您可以使用以下代码轻松访问“每个请求”生命周期范围,给出一个实例IComponentContext

ctx => {
  var requestScope = ctx.Resolve<IHttpContextAccessor>().HttpContext.GetLifetimeScope();

  var shortLived = requestScope.Resolve<ShortLived>();
}

在传统的ASP.NET中,有一个“依赖性解析器”而不是“服务提供者”。

例如GlobalConfiguration.Configuration.DependencyResolver= 在这里集成autofac

解决这个问题ILifetimeScope有点麻烦。

public static ILifetimeScope GetLifetimeScope(this HttpContext httpContext)
{
    var requestMessage = httpContext.Items["MS_HttpRequestMessage"] as HttpRequestMessage;

    return requestMessage?.GetDependencyScope().GetService(typeof(ILifetimeScope)) as ILifetimeScope;
}
var requestScope = HttpContext.Current.GetLifetimeScope();

var shortLived = requestScope.Resolve<ShortLived>();

热门问答

使用文档遇到问题,可以找谁处理?

请叫我雷锋!腾讯云文档有“文档反馈”的功能,直接在文档页面就可以反馈,反馈还有 礼品 ~ 云+社区:问答.png ... 展开详请

直播间IM消息可以下载到自己服务器备份吗?

人生的旅途辣鸡前端
推荐
目前仅私有群(Private)、公开群(Public)和聊天室(ChatRoom)具备消息漫游能力(默认7天)。核实下您那边的群组类型看是否支持https://cloud.tencent.com/document/product/269/1502#.E6.B6.88.E6.81....... 展开详请

腾讯云容器加速地址是错的?

推荐已采纳

我刚才测试了一下,这个加速器地址可以用额,你这边是怎么测试出是关闭状态的啊?

加速器地址是不能直接用浏览器访问的,阿里云提供的直接访问也是空

webIM添加组员报错?

无聊至极互联网重度用户
推荐已采纳

付费超过组数限制,核实下是否超过限制

https://cloud.tencent.com/document/product/269/11673#.E5.8A.9F.E8.83.BD.E5.AF.B9.E6.AF.94

Tencent iot-sdk-embedded-c在Windows下编译出错:无法解析外部符号?

无聊至极互联网重度用户
推荐已采纳

腾讯云IM调用 add_group_member提示该群不能邀请成员?

推荐已采纳
是什么类型的群?根据相应类型的邀请他人入群的控制项,对照文档看下是否允许邀请他人入群。 参考文档:https://cloud.tencent.com/document/product/269/1502#.E7.BE.A4.E6.88.90.E5.91.98.E6.93.8D.E4...... 展开详请

扫码关注云+社区

领取腾讯云代金券