2016-06-21 2 views
0

私はこのアプリケーションをIOC(autofac)を使ってどこに持っていますか?その間、私は工場が必要な位置に自分を見つけました。工場の中で私は依存関係のある新しいオブジェクトを作成します - だから私はこれらと結婚することができますか?工場とIOCは一緒に - 両方の使い方は?

public class SubscriptionHandlerFactory : ISubscriptionHandlerFactory 
{ 
    public ISubscriptionHandler GetProvider(StreamType streamType) 
    { 
     switch (streamType) 
     { 
      case StreamType.Rss: 
       return new RssSubscriptionHandler(null,null,null,null); 
      case StreamType.Person: 
       return new PersonSubscriptionHandler(null, null, null, null); 
      default: 
       throw new ArgumentOutOfRangeException(nameof(streamType), streamType, null); 
     } 
    } 
} 
+1

工場にIoCコンテナを注入して、その上に公開されているメソッドを使用して、必要な具体的な型のインスタンスを取得します。その後、コンテナはあなたのための他の依存関係を解決します。 –

+0

@MartinCostelloはサービスロケータで、工場内で行われたとしても、主に反パターンとみなされます。 –

+0

あなたは工場が必要ですか? IoCコンテナにオブジェクト依存グラフを作成させることができないのはなぜですか? –

答えて

1

あなたはnamed and keyed serviceを使用して、このようになります。IIndex<TKey, TService>

登録を使用してインスタンスを取得できます。

このような
builder.RegisterType<RssHandler>().Keyed<ISubscriptionHandler>(StreamType.Rss); 
builder.RegisterType<PersonHandler>().Keyed<ISubscriptionHandler>(StreamType.Person); 
builder.RegisterType<SubscriptionHandlerFactory>().As<ISubscriptionHandlerFactory>(); 

と工場:

public class SubscriptionHandlerFactory : ISubscriptionHandlerFactory 
{ 
    public SubscriptionHandlerFactory(IIndex<StreamType, ISubscriptionHandler> handlers) 
    { 
     this._handlers = handlers; 
    } 

    private readonly IIndex<StreamType, ISubscriptionHandler> _handlers; 

    public ISubscriptionHandler GetProvider(StreamType streamType) 
    { 
     return this._handlers[streamType]; 
    } 
} 
+0

これは素晴らしいです。私はまた、IIファックスをautofacに接続しないように抽象化することができます。 – jstadnicki

+0

実際、工場はその工場の顧客の視点から、自動ファクシミリの抽象化になっています。それはさらに優れています! – jstadnicki

0

IoCを使用して、オブジェクトのインスタンス化を永遠に抽象化することはできません。ある時点で、具体的なインスタンスを作成する必要があります(工場やIoCコンテナ内にある)

あなたの工場にオートファックコンテナを注入することも、工場自体がインターフェイスを実装することもできますあなたのファクトリの異なるバージョンは、クラスに必要なものにすることができます(ユニットテストのために別の工場が必要な場合など)

0

私はそれを解決します。やや。私はAutofacに依存したいと思っていなかったので、自己それは自己破裂した。しかし、@ martin-costelloのおかげで、私はautofacを取る必要はないかもしれないが、IDependencyResolverをビルドするのはそれほど悪くないかもしれないということになった。 autofacをIDependencyResolverとして登録することができなかったので、私はIDependencyResolverとしてDependencyResolverを登録します。もう一歩近づく。 Autofac DependencyResolver.SetResolverの前に登録が行われるので、私は最終的に私の問題を解決するLazyを使う必要がありました。

は、ここでは、コード(または私が見つけた、少なくとも最善の解決策)

// other registration 
builder.RegisterType<RssSubscriptionHandler>(); 
builder.RegisterType<PersonSubscriptionHandler>(); 
// even more registration here 

builder.RegisterType<SubscriptionHandlerFactory>() 
     .As<ISubscriptionHandlerFactory>() 
     .WithParameter(new TypedParameter(typeof(Lazy<IDependencyResolver>), 
         new Lazy<IDependencyResolver>(() => DependencyResolver.Current))); 

だ後(クリーンアップの前に)これまで工場の変更:

public class SubscriptionHandlerFactory : ISubscriptionHandlerFactory 
{ 
    private readonly Lazy<IDependencyResolver> resolver; 

    public SubscriptionHandlerFactory(Lazy<IDependencyResolver> resolver) 
    { 
     this.resolver = resolver; 
    } 

    public ISubscriptionHandler GetProvider(StreamType streamType) 
    { 
     switch (streamType) 
     { 
      case StreamType.Rss: 
       return (ISubscriptionHandler)this.resolver.Value.GetService(typeof(RssSubscriptionHandler)); 
      case StreamType.Person: 
       return (ISubscriptionHandler)this.resolver.Value.GetService(typeof(PersonSubscriptionHandler)); 
      default: 
       throw new ArgumentOutOfRangeException(nameof(streamType), streamType, null); 
     } 
    } 
} 

これ今のところは/最高/きれいですそれほど悪くない/具体的でない/抽象的である/私が把握することができたすべての解決策。コメント歓迎。

関連する問題