8

一部のモジュール自体に依存関係があるため、Autofac コンポーネントの登録をモジュールに整理する方法に苦労しています。

インターフェイスに構成データの抽象化 (つまり、web.config)を実装しました。

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

WebConfigurationProviderASP.NET ( ) および「デスクトップ」アプリケーション ( )の実装と共にExeConfigurationProvider

私の 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 */);
    }
}

拡張メソッドは登録デリゲート ( )RegisterType()を受け入れないため、前もって登録してから、構成で指定された型を登録するときにそれを解決することはできません。たとえば、次のようになります。Func<IComponentContext, T>Register()IConfigurationProvider

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

これは、依存関係のあるモジュールとないモジュールを登録できる必要があることを意味しますIConfigurationProvider

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

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

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

基本的なタスクを達成するためのより簡単な方法が必要です。インターフェイスを介して提供される構成で指定された型を登録しますよね? では、どうすればいいですか?

4

2 に答える 2

7

次のようなことができます。

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
    {
    }
}
于 2012-06-19T02:07:55.493 に答える
2

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

モジュールをコードに登録し、config からパラメーターを受け取ることを可能にする、Paul Stovell による優れた代替手段があります。お役に立てれば!

于 2012-07-04T21:15:24.577 に答える