首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >带有Autofac的强制依赖

带有Autofac的强制依赖
EN

Stack Overflow用户
提问于 2017-03-24 22:14:51
回答 1查看 510关注 0票数 2

我正在寻找一种最干净的方法来解决autofac的强制依赖问题。

我有一个短暂的类,它将根据LifeTimeScope进行注册:

代码语言:javascript
复制
public class ShortLived
{
    public void DoSomethingUsefull() {}
}

我有一个长期存在的类,它将被注册为单实例。它依赖于ShortLived类:

代码语言:javascript
复制
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。

代码语言:javascript
复制
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();
    }
}

下面的方法是可行的。但我真的希望有一个更好的解决问题的方法,而不是依赖于某种静态变量。

代码语言:javascript
复制
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管道的LifeTimeScope中注册。

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

EN

回答 1

Stack Overflow用户

发布于 2017-03-31 17:04:09

如果在容器中注册了类型T,Autofac将自动解析Func上的依赖项,因为通过容器创建T实例的工厂请查找有关委托工厂的更多信息

注册您的ShortLived类,如下所示,现在一切正常。

代码语言:javascript
复制
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();
    //}
}

您也可以直接从容器中解析,使用不再需要,但最终是您的选择

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43001786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档