2016-08-24 7 views
0

何度も私がLazy<T>パターンを実装する必要があると、Lazyの実装を隠すためにパターン全体をクラスに入れるという考えが私の頭に浮かんだ。これを行うにLazyをカプセル化する<T>

public interface IConfigurationProvider<T> 
{ 
    T GetConfiguration(); 
} 

public abstract class SingletonConfigurationProvider<TConfiguration> : IConfigurationProvider<TConfiguration> 
{ 
    private static readonly Lazy<TConfiguration> _lazy = 
     new Lazy<TConfiguration>(_loadConfiguration); 

    private static Func<TConfiguration> _loadConfiguration; 

    private SingletonConfigurationProvider() { } 
    public SingletonConfigurationProvider(Func<TConfiguration> LoadConfig) 
    { 
     _loadConfiguration = LoadConfig; 
    } 

    public TConfiguration GetConfiguration() 
    { 
     return _lazy.Value; 
    } 
} 

私の目標は、取得することである、「外」シンプルさから:「私のサービスのためにシングルトン設定オブジェクトのロード」の場合は

、私はこのような何かをした

public class ConfigTest : SingletonConfigurationProvider<ObjectTest> 
{ 
    public ConfigTest() 
     : base(Load) 
    { 
    } 

    public static ObjectTest Load() 
    { 
     return new ObjectTest() 
     { 
      testInt = 3, 
      testString = "Hi" 
     }; 
    } 
} 

のポイントは以下のとおりです。

  • TypeInitialization Exceptio」と、それはコンパイルが、それは実行時に壊れますn "は_loadConfigurationをnullにすることはできません。それはSingletonConfigurationProviderコンストラクタの前に怠惰が構築されているからでしょうか?
  • シングルトンの意味を壊さずに私が望むものを達成することは可能でしょうか?
+3

基本的には、静的フィールドとゲッターという2行のコードの抽象化を構築しています。それは本当にそれの価値があるのですか? – Sinatr

+1

_loadConfigurationがnullの場合、_lazyを初期化する最初の行に問題がある可能性があります。オーバーロードされたコンストラクタに初期化を移動してみてください。 – Sarathy

+0

@Sarathyこの場合_lazyは読み取り専用ではありません –

答えて

1

あなたが探している抽象化は、のメモ機能です。この種の関数では、getter関数を変更して 'execute-it-only-once'パターンのパターンを実装します。テストされていないコードですが、

public Func<T> Memoize(Func<T> slowFunction) { 
    bool evaluated = false; 
    T value = default(T); 

    return() => { 
     if (!evaluated) { 
      value = slowFunction(); 
      evaluated = true; 
     } 

     return value; 
    }; 
} 

これで、このように使用できる機能ができました。

Func<TConfiguration> onceOnlyLoad = Memoise(Load); 

好きなように今、あなたはonceOnlyLoad()何度でも呼び出すことができますし、それだけであなたはそれを呼び出すコンフィグ初めてのロードます。

場合によっては、Lazy<T>を内部的に使用して同じ動作を実行できます。あなた次第。

関連する問題