2009-04-14 14 views
4

私はそれが高速であることをオートファックについて読んだことがあります。私はコーディングが関わっていることを見てきました。しかし、私はそれをどのように使用するかについてはあまりよく分かりません。私はStructureMapを使用しましたが、静的なObjectFactoryを持っています。 Ninjectカーネルを持っていますが、彼らはこのような何かやってお勧めautofacのGoogleのページに:、オートファックのメリットとデメリット

using(var resolver = builder.Build()){ 
    var whatINeed = resolver.Resolve<INeedThisService>(); 
} 

をこれは、WinFormsのアプリですので、私は上記をやってから、無効なオブジェクトの状態を得たので、私はグローバルいるIContainerを有することにswichedこのようにしました

using(var resolver = Program.Container.CreateInnerContainer()) 
{ 
    var whatINeed = resolver.Resolve<INeedThisService>(); 
} 

私はこれを約3〜5回使いました。しかし、それは不完全ですか?または私はちょうど

var whatINeed = Program.Resolve<INeedThisService>() 

internal static TServervice Resolver<TService>(){ 
     if(_container == null) _container = builder.Build(); 
     return _container.Resolve<TService>(); 
} 

WICHは、使用、そしてなぜでしょうカバーの下のような何かを行う必要があります。また、CreateInnerContainer()での作業には不利益がありますか?

答えて

8

私はAutoFacのエキスパートではありませんが、他のIocコンテナでの経験はあります。私はこの質問が私にAutoFacを試みる理由を与えるだろうと思った。

IOCコンテナに基づく設計は、エントリ・ポイントまたはホスト・レベル以外のすべてのコードがコンテナにアクセスできないようにしなければなりません。私はAutoFacとWinFormsを使ってフォームがどのようにコンストラクタ経由でサービスにアクセスできるかを示す次の例を作成しました。

なぜあなたは内側のコンテナが必要だと思ったのですか?おそらくあなたはコメントして、より詳細な回答を提供することができます。

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     var builder = new ContainerBuilder(); 
     builder.Register<TheService>().As<INeedThisService>(); 
     builder.Register(f => new Form1(f.Resolve<INeedThisService>())).As<Form1>(); 

     using (var container = builder.Build()) 
     { 
      Application.Run(container.Resolve<Form1>()); 
     } 

    } 
} 

public interface INeedThisService { } 

public class TheService : INeedThisService 
{ 
    public TheService() { Console.WriteLine("ctor ThisService"); } 
} 

public partial class Form1 : Form 
{ 
    public Form1(INeedThisService service) 
    { 
     Console.WriteLine("ctor Form1"); 
     InitializeComponent(); 
    } 
} 
+0

私はどのように知っていますIoCを使用すると、私は自分のサービスにアクセスするためのフレームワークのガイドラインにあったものを望んでいました。 StructureMapは明確なソリューションです。ObjectFactoryを使用するだけです。しかし、Autofacではそれほど明確ではないので、すべてのコンポーネントを再登録する必要はありません。 –

+0

すべてのコンポーネントを「再登録する」という意味を説明できますか?アセンブリ内のすべてのタイプの自動登録をお探しですか?その間にStructureMapのObjectFactoryを見ていきます。 –

+0

再登録とは、IContainerを再生成する部分を再度実行することを意味します。問題は、using(..)ステートメントでIContainerを実行する場合、IContainerを保持する方法でした。 –

3

Mark Lindell氏は、通常、Autofacアプリケーションで直接コンテナにアクセスする必要はないと指摘しています。

マークアップのように、アプリケーションの起動時に1回アクセスすることをお勧めします。

オブジェクトを後で作成する必要があるその他のコンポーネントは、Autofacが自動的に挿入するIContextタイプのコンストラクタパラメータを宣言することができます。このことができますhttp://code.google.com/p/autofac/wiki/DelegateFactories

希望:

Autofacアセンブリの依存関係を必要としない代わりに、で説明したように生成された工場を使用することです!

+0

申し訳ありませんが、一般的なガイドラインではまだ明確ではありません。 GeneratedFactoriesは面白いアプローチです。 –

5

1)私があなたが主にサービスロケータとしてIOCコンテナを使用しようとしていると仮定することができました。ほとんどすべてのコンテナでサポートされていますが、主な用途は依存性注入です。つまり、Resolveメソッドをまったく呼び出さず、コンテナにすべての依存関係を注入させないようにする必要があります。これらの2つの違い(Service LocatorとDependency Injection)は、このトピックを超えています。

2)まだサービスロケータとして使用したい場合は、内側のコンテナを作成せずにルートコンテナ(Program.Container)を使用することができます。順序は次のようになります。

  • 登録あなたのコンポーネントビルダーでContainerBuilderを作成
  • ルートコンテナを作成します。builder.Build()
  • アクセスルートコンテナをコンポーネントのインスタンスを解決するために

3)コンテナ階層は、異なるスコープでシングルトン動作が必要なシナリオで役に立ちます。

  • グローバル\セッション\要求(Webアプリケーション)
  • アプリケーション\プラグイン(デスクトッププラグインベースのアプリケーション)

ところでAutofacは、このような問題を解決するためにtagged contextsを使用する人々を励ます:

+1

はい、私はサービスロケータとDIとして使用しようとしていました。私は当時混乱していました。なぜなら、主に私がStructureMapをどのように使用していたかが原因です。 –

関連する問題