2017-03-24 9 views
1

私は、autofacのCaptive Dependency問題を解決する最もクリーンな方法を探しています。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(); 
    } 
} 

いくつかのbackroundのに関する情報: 私はOWINに取り組んでいるがASP.Net WebApi2 Microserviceを開催しました。他のサービスを呼び出すときは、currentOwinContext.Request.User.Identityから値を読み取り、それらを次のサービスに送るRequestMessageに追加する必要があります。私のLongLivedクラスはDelegatingHandler(つまり、HttpClient "HttpMessageHandler-Pipeline"の一部)であり、HttpClientは.SingleInstance()である必要があるので、私が行う各リクエストに対して新しいHttpClientをインスタンス化する必要はありません。 ShortLivedクラスはIOwinContextで、OwinパイプラインのLifeTimeScopeに登録されています。

currentLifeTimeScopeの静的変数の代わりに、私はautofacにHttpConfigurationを登録することができました。次に、httpConfig.DependencyResolver.GetRequestLifetimeScope()でcurrentLifeTimeScopeを取得できます。私はまだこのアプローチをテストしていません。私はまだ何かを清潔にしたいと思っています。タイプTがコンテナに登録されている場合

答えて

1

、Autofacは自動的にコンテナを通じてTのインスタンスを作成し、工場とし​​ての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(); 
    //} 
} 

、あなたが直接使用して、コンテナからだけでなく解決できる必要はなくなりましたが、最後の選択肢であなた

です
関連する問題