2011-01-12 18 views
0

これは確かにあなたのほとんどのための基本的な質問ですが、私はそれについて考えてもまだ頭痛を与えています。私のアプリケーションのアーキテクチャ

私はインスタンス化されるドメイン名をとり、リポジトリクラスを持っている:

public class RepositoryUserAD : IRepositoryUserAD , IDisposable 
{ 
    PrincipalContext context; 

    public RepositoryUserAD(string domainName) 
    { 
    if (string.IsNullOrEmpty(domainName)) 
     throw new Exception("the domainName cannot be null or empty"); 
    DomainName = domainName; 
    context = new PrincipalContext(ContextType.Domain, DomainName); 
    } 

    public UserPrincipal GetUser(string username) 
    { 
    UserPrincipal foundUser = null; 
    foundUser = UserPrincipal.FindByIdentity(context, username); 
    return foundUser; 
    } 

    public void Dispose() 
    { 
    context.Dispose(); 
    } 
} 

そしてここでは私の問題です。私がこれのように働くなら、それは大丈夫ですが、私は私の文脈をクラスで開き、クラスを処分するのをやめたいのです。 私はブロックを使用することもできますが、私はコンテキストへの参照、オブジェクトへの参照、または少なくとも私が最初に取得しなかったプロパティを失うため、別の問題に直面しています。

私のアーキテクチャは、私の一般的なアプローチで、私はサービスで私のクエリをフィルタリングし、実際にデータをフェッチするためにリポジトリを頼むことができるように言っているだろうので、私は二つに引き裂かれています以下の

Repository r = new Repository(); 
Service s = new Service(r); 

です。しかし、ここで広告では、リポジトリレベルでの接続を開いたり閉じたりできません。柔軟性が失われ、リポジトリはすべてを取得しています。

私の頭の中でもどちらかが明確ではないので、すべてが明確ではありません。ご支援のための

おかげで、

+0

「私の文脈をクラスで開き、クラスを処分するのが嫌いです」何故なの?あなたが実際にそれをしたくない場合は、呼び出し側にコンテキストを提供(および処分)するよう要求することができます。 –

答えて

0

&を作成するだけの理由があると仮定していますが、それぞれの手法のコンテキストを破壊するのは効率的ですか?

私はコンテキストを何らかの形でキャッシュするコンテキストファクトリを作成します。

public class ContextFactory { 
     private List<PrincipalContext> contexts = new List<PrincipalContext>(); 
     public PrincipalContext GetPrincipalContext(ContextType contextType, string domainName) 
     { 
      PrincipalContext existingContext = contexts.First(item=>item.ContextType==contextType && 
       item.DomainName == domainName); 
      if (existingContext == null) { 
       existingContext = new PrincipalContext(contextType,domainName); 
       contexts.Add(existingContext); 
      } 
      return(existingContext); 
     } 
    } 
    public void Dispose() 
    { 
     foreach (PrincipalContext context in contexts) { 
      context.Dispose(); 
     } 
    } 
} 

次にあなたがこれを使いたいどんな範囲で、クラスの新しいインスタンスを作成し、コンテキストを取得するためにそれを使用し、最後にそれを処分。これがWebアプリケーションの場合は、1ページの範囲を超えて使用するのは難しいでしょうが、コンテキストのセッションキャッシュを作成して、そのオブジェクトを定期的に廃棄することもできます。時間。また、このコードは競合状態になるので、それに対処する必要がありますが、これは基本的な考え方です。これは、基本的に接続プーリングが動作する方法に似ています。

+0

実際、あなたの拳の声明は、「あなたは単に各方法のコンテキストを作成して破壊するだけではありません。 – Arthis

+0

ハハ!さて、単純な答えはとても単純なように思えました。私は、これがどんな状況であってもコンテキストを作成するオーバーヘッドについてわからないものがなければならないと考えました...とにかくうまくいきました。 –

0

Serviceクラスは何をしますか?

これはどう:

public class RepositoryUserAD : IRepositoryUserAD 
{ 
    private readonly PrincipalContext context; 

    public RepositoryUserAD(PrincipalContext c) 
    { 
     context = c; 
    } 

    public UserPrincipal GetUser(string username) 
    { 

    return UserPrincipal.FindByIdentity(context, username); 

    }   
} 

リポジトリにコンテキストを注入することにより、リポジトリはもはやコンテキストを処分する際に決定する責任がありません。リポジトリの「呼び出し元」はそれを担当しています。これは、リポジトリがPrincipalContextが少し後で(たとえば別のリポジトリによって)必要であるかどうかを知らないので、良いことです。