5

AutoFac 2forDIを使用するアプリケーションを構築しています。静的なIoCHelper(Service Locator)の使用は避けるべきだと読んでいます。

IoCHelper.cs

public static class IoCHelper
{
    private static AutofacDependencyResolver _resolver;

    public static void InitializeWith(AutofacDependencyResolver resolver)
    {
        _resolver = resolver;
    }

    public static T Resolve<T>()
    {
        return _resolver.Resolve<T>();
    }
}

前の質問への回答から、自動生成されたファクトリを使用して、UnitOfWorkでIoCHelperを使用する必要性を減らす方法を見つけました。この道を進み続けると、IoCHelperを完全に排除できるかどうか興味があります。

シナリオは次のとおりです。

構成実装のラッパーとして機能する静的Settingsクラスがあります。Settingsクラスは他のクラスの大部分への依存関係であるため、ラッパーを使用すると、アプリケーション全体に設定クラスを挿入する必要がなくなります。

Settings.cs

public static class Settings
{
    public static IAppSettings AppSettings
    {
        get
        {
            return IoCHelper.Resolve<IAppSettings>();
        }
    }
}

public interface IAppSettings
{
    string Setting1 { get; }
    string Setting2 { get; }
}

public class AppSettings : IAppSettings
{
    public string Setting1
    {
        get
        {
            return GetSettings().AppSettings["setting1"];
        }
    }

    public string Setting2
    {
        get
        {
            return GetSettings().AppSettings["setting2"];
        }
    }

    protected static IConfigurationSettings GetSettings()
    {
        return IoCHelper.Resolve<IConfigurationSettings>();
    }
}

サービスロケーターを使用せずに、またすべてのクラスにAppSettingsを挿入する必要なしに、これを処理する方法はありますか?以下にリストされているのは、コンストラクターインジェクションの代わりにServiceLocatorに頼り続ける3つの領域です。

  • AppSettings
  • ロギング
  • キャッシング
4

1 に答える 1

4

IAppSettingsへの隠れた依存関係からそれらをきれいに保つためだけに、それを必要とするすべてのクラスに注入したいと思いますSettings。質問は、その依存関係をすべてのクラスに散りばめる必要があるかということです。

本当に静的Settingsクラスを使用したい場合は、少なくともテストしやすい/偽造できるようにします。このことを考慮:

public static class Settings
{
    public static Func<IAppSettings> AppSettings { get; set; }
}

そして、コンテナを構築する場所:

var builder = new ContainerBuilder();
...
var container = builder.Build();

Settings.AppSettings = () => container.Resolve<IAppSettings>();

これにより、テスト中に偽物と交換できます。

Settings.AppSettings = () => new Mock<IAppSettings>().Object;

これで、AppSettings通常のコンストラクター インジェクションで実行できるクラス (そのうちの 1 つしかないと仮定します)。また、設定プロパティへの呼び出しごとに解決を行いたいと考えているため、必要に応じてインスタンスを取得するファクトリ デリゲートを挿入します。これが必要ない場合は、もちろんIConfigurationSettingsサービスを直接注入する必要があります。

public class AppSettings : IAppSettings
{
    private readonly Func<IConfigurationSettings> _configurationSettings;

    public AppSettings(Func<IConfigurationSettings> configurationSettings)
    {
        _configurationSettings = configurationSettings;
    }

    public string Setting1
    {
        get
        {
            return _configurationSettings().AppSettings["setting1"];
        }
    }

    public string Setting2
    {
        get
        {
            return _configurationSettings().AppSettings["setting2"];
        }
    }
}
于 2010-04-29T14:30:06.087 に答える