2012-06-18 17 views
6

モジュールの中には、依存関係のあるモジュールがあるため、Autofacコンポーネントの登録をどのように体系化するのかが苦労しています。独自の依存関係を持つAutofacモジュール

私はインターフェイスのコンフィギュレーションデータの抽象化(すなわちweb.configファイル)を実装しました:ASP.NETの実装(WebConfigurationProvider)と "デスクトップ" アプリケーション(ExeConfigurationProvider)と一緒に

interface IConfigurationProvider 
{ 
    T GetSection<T>(string sectionName) 
     where T : System.Configuration.ConfigurationSection; 
} 

を。

私autofacモジュールのいくつかは、コンストラクタのパラメータとしてIConfigurationProviderを必要とするが、一部にはありません。

class DependentModule : Module 
{ 
    public DependentModule(IConfigurationProvider config) 
    { 
     _config = config; 
    } 

    protected override void Load(ContainerBuilder builder) 
    { 
     var configSection = _config.GetSection<CustomConfigSection>("customSection"); 
     builder.RegisterType(configSection.TypeFromConfig); 
    } 

    private readonly IConfigurationProvider _config; 
} 

class IndependentModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.Register(/* other stuff not based on configuration */); 
    } 
} 

Register()が行うようRegisterType()拡張メソッドは、登録デリゲート(Func<IComponentContext, T>)を受け入れていないので、これがあることを意味

// this would be nice... 
builder.RegisterType(c => c.Resolve<IConfigurationProvider>().GetSection<CustomConfigSection>("sectionName").TypeFromConfig); 

:、私は、のようなものをアップフロントIConfigurationProviderを登録して、私は設定で指定された型を登録するために行くときにそれを解決することはできません私はモジュールを登録する必要があります。にはIConfigurationProviderの依存関係があります。

それは手動で各モジュールをインスタンス化し、それを登録する方法は明らかです:

IConfigurationProvider configProvider = ...; 
var builder = new ContainerBuilder(); 
builder.RegisterModule(new DependentModule(configProvider)); 
builder.RegisterModule(new IndependentModule()); 
using (var container = builder.Build()) 
{ 
    ... 
} 

しかし、私は手動で私のモジュールをインスタンス化する必要はありません - 私は、モジュール用のアセンブリをスキャンし、説明したように(自動的に登録したいin this question )。ですから、IModuleタイプのアセンブリをスキャンするためにリフレクションを使用し、Activator.CreateInstanceを使用して登録可能なインスタンスを作成する必要があります。しかし、コンストラクタのパラメータとしてIConfigurationProviderを渡すかどうかは、どのようにしてわかりますか?そして、他のモジュールが追加または異なる依存関係を持つとどうなりますか?

基本的なタスクを達成するためのより簡単な方法があるはずです。インターフェイス経由で提供される設定で指定されたタイプを登録しますか?だから私はそれをどうやってやるの?あなたはこのような何か行うことができます

+0

これを最後に解決しましたか?私は非常に似たようなケースがありますが、私の依存関係は別の依存関係を持っています(私はdbから設定を取得したいので、IRepoConfigに依存するIConfigProviderを持っています) – Learner

+0

@Learner、私はもともとAutofacとMEFの組み合わせ下のJim Bollaの答えの後で、それは恐ろしく複雑で、私はあまりにも長くそれを取り除いた。私は従属モジュールをもう持っていません。私の主な使用事例は 'Type'に基づいた選択だったので、私はすべての**登録**の候補者を登録して*解決しました*プロパティは 'ConfigurationSection'から来ます。もしあなたが望むなら、私はあなたにサンプルコードを送ることができます。 –

+0

ありがとう、ありがとう。私は私のケースではConfigurationSection/xmlを使うことはできないと思う。 – Learner

答えて

6

:このシナリオでは

using System.Collections.Generic; 
using System.Linq; 
using Autofac; 
using Autofac.Core; 
using NUnit.Framework; 

namespace Yo_dawg 
{ 
    [TestFixture] 
    public class I_heard_you_like_containers 
    { 
     [Test] 
     public void So_we_built_a_container_to_build_your_container() 
     { 
      var modules = GetModules(); 
      Assert.That(modules.Length, Is.EqualTo(4)); 

      var builder = new ContainerBuilder(); 

      foreach (var module in modules) 
       builder.RegisterModule(module); 

      var container = builder.Build(); 
     } 

     private IModule[] GetModules() 
     { 
      var builder = new ContainerBuilder(); 

      var configurationProvider = new ConfigurationProvider(); 
      builder.RegisterInstance(configurationProvider).AsImplementedInterfaces().ExternallyOwned(); 

      builder.RegisterAssemblyTypes(GetType().Assembly) 
       .Where(t => t.IsAssignableTo<IModule>()) 
       .AsImplementedInterfaces(); 

      using (var container = builder.Build()) 
       return container.Resolve<IEnumerable<IModule>>().ToArray(); 
     } 
    } 

    public class ModuleA : Module 
    { 
     public ModuleA(IConfigurationProvider config) 
     { 
     } 
    } 

    public class ModuleB : Module 
    { 
     public ModuleB(IConfigurationProvider config) 
     { 
     } 
    } 

    public class ModuleC : Module 
    { 
    } 

    public class ModuleD : Module 
    { 
    } 


    public interface IConfigurationProvider 
    { 
    } 

    public class ConfigurationProvider : IConfigurationProvider 
    { 
    } 
} 
+0

あなたの提案をありがとう。私も同様の戦略を追求しましたが、その側面は好きではありませんでした。私はこのアプローチを再検討しなければならないでしょう。 –

2

を、Autofac独自のXML設定を使用すると、ターゲットとしているシナリオをカバーするようです。新しいIConfigurationProviderメカニズムを追加することは、すでにコンテナによって提供されているこの機能を再発明するように思えます。基本については、https://code.google.com/p/autofac/wiki/XmlConfigurationに記載されています。構成構文には、モジュールの組み込みサポートがあります。

Paul Stovellには、モジュールがコードに登録されているにもかかわらず、configからパラメータを受け取ることができる素晴らしい選択肢があります - http://www.paulstovell.com/convention-configurationを参照してください。お役に立てれば!

+0

返事をありがとうが、私はこのシナリオで私のAutofac設定をXMLで表現することがどのように役立つのか理解できません。おそらく、私はちょっと私の質問でコードを混乱させたので、私はカスタムSectionHandler型で作業しようとしているというアイデアをよりよく表現するように編集しました。 –

関連する問題