2017-03-24 107 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(); 
    //} 
} 

,您可以直接使用,不再需要容器,但最后选择解决以及是你