1

私は、WebアプリケーションでIoCを実装する詳細については、Microsoft.Practices.ServiceLocationを活用する方法で作業してきました。私は特にAutofacとasp.netの統合を使用していますが、私は自分自身を他のコンテナに公開したいと思っていました。 this questionの行に沿って、私はWebアプリケーションコードでコンテナにアクセスする方法を心配していました。Autofac、ASP.NET、Microsoft.Practices.ServiceLocation

私は主に解決されるべきインターフェイスを定義する「コア」ライブラリを持っています。このコアライブラリは、私のWebアプリケーションや他のアプリケーションでも使用されています。共通インタフェースを定義するのに非常に便利です。私はこれがIoCコンテナにアクセスするのに最適な場所だと思っていましたが、私は静的クラスでそれを行いました。そのトリックは、静的クラスにコンテナを注入することです。

コンテナはリクエストごとに異なる可能性がありますが、ウェブ以外のアプリではおそらく常に同じになるため、ウェブ環境では問題があります。最初に、メソッドdirecltyをコンテナに注入しようとしましたが、次のWebリクエストですぐに失敗しました!だから私はこの思い付いた:

public static class IoCContainer 
{ 
    public static void SetServiceLocator(Func<IServiceLocator> getLocator) 
    { 
     m_GetLocator = getLocator; 
    } 
    static private Func<IServiceLocator> m_GetLocator = null; 

    public static T GetInstance<T>(string typeName) 
    { 
     return m_GetLocator().GetInstance<T>(typeName); 
    } 
} 

は今私のglobal.asax.csに私はこれを実行します。

protected void Application_Start(object sender, EventArgs e) 
{ 
    var builder = new Autofac.Builder.ContainerBuilder(); 
    ... register stuff ... 
    var container = builder.Build(); 
    _containerProvider = new Autofac.Integration.Web.ContainerProvider(container); 
    Xyz.Core.IoCContainer.SetServiceLocator(() => 
     new AutofacContrib.CommonServiceLocator.AutofacServiceLocator 
      (_containerProvider.RequestContainer)); 
} 
public IContainerProvider ContainerProvider 
{ 
    get { return _containerProvider; } 
} 
static IContainerProvider _containerProvider; 

をと依存性を解決するために呼び出すのではなく

var someService = Xyz.Core.GetInstance<ISomeService>(); 

のように見えます特定のコンテナを渡すコンテナを取得する方法を知っている代理人を渡します。非Webアプリケーションの場合、デリゲートはおそらく単にbuilder.Build()が処理するものを返します。

私の専門家への質問は、これは意味がありますか?私は、コンテナ製品が何であるか、コンテナ自体がどこから来るのかを知らなくても、依存関係を解決できる何かに簡単にアクセスできます。どう思いますか?

答えて

2

私は、IoCが非DIアーキテクチャに導入されたことが主な理由で、同様のパターンを使用します。したがって、明示的にコンテナを呼び出してサービスを取得する必要があります。これは基本的にFactoryパターンです。

すべての依存関係を注入でき、コードがサービスロケータに依存しなくなった場合、IoCの真の利点が実現します。 Autofac.Integration.Webには、ページオブジェクトへの注入を実行するハンドラがあり、静的サービスロケータを廃止します。これは好ましい方法ですが、(私たちの場合もそうですが)サービスロケータを避けることはできません。

これは、既にIoCContainerクラスを使用してコンテナからアプリケーションを分離しているため、IoCContainer内でAutofacServiceLocatorをさらに抽象化する理由はありません。要するに、IoCContainerはすでにサービスロケータであり、コンテナ実装への直接アクセスを「許可」する必要があります。ここで

は、あなたのサービスロケータクラスの私の感想です:

public static class IoCContainer 
{ 
    private static IContext GetContainer() 
    { 
     var cpa = 
      (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance; 
     return cpa.ContainerProvider.RequestContainer; 
    } 

    public static T GetInstance<T>() 
    { 
     return GetContainer().Resolve<T>(); 
    } 
} 
+0

これはピーター非常にクールですが、私がいなくても、Webベースの、おそらく、他の文脈では、私の「.Core」ライブラリを再利用できるように期待していました。それでも、抽象度があまりにも高い抽象化を回避するのに役立つので、これは大きな答えだと思います。ありがとう! – n8wrl

+0

私はあなたのポイントを見ます。それでも、サービスロケータパターンを完全になくし、依存性注入のみを使用することができれば、この問題をまったく解決する必要はありません:) –

関連する問題