C# 我的应用程序的体系结构

C# 我的应用程序的体系结构,c#,architecture,C#,Architecture,对你们大多数人来说,这无疑是一个基本问题,但当我想到它时,它仍然让我头疼 我有一个存储库类,它接受要实例化的域名: public class RepositoryUserAD : IRepositoryUserAD , IDisposable { PrincipalContext context; public RepositoryUserAD(string domainName) { if (string.IsNullOrEmpty(domainName))

对你们大多数人来说,这无疑是一个基本问题,但当我想到它时,它仍然让我头疼

我有一个存储库类,它接受要实例化的域名:

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();
   }
}

这是我的问题。如果我是这样工作的,这是可以的,但我不喜欢让我的上下文与类一起打开,并在处理类时关闭。 我也可以使用using块,但是我面临另一个问题,因为我失去了对上下文的引用,从而失去了对对象的引用,或者至少失去了对我没有首先获得的属性的引用

我的架构如下

Repository r = new Repository();
Service s = new Service(r);
我一分为二,因为在我的一般方法中,我希望能够在服务中过滤我的查询,并要求存储库真正获取数据。但是这里有了广告,我无法在存储库级别打开和关闭我的连接,否则我将失去灵活性,存储库将获取所有内容

一切都不清楚,因为在我的脑海里也不清楚,我只是希望有人能告诉我一个走出这一切的方法

感谢您的支持,

服务类做什么

这个怎么样:

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在稍后是否还需要另一个存储库,例如。

我假设您不只是为每个方法创建和销毁上下文是有原因的,效率如何

我会创建一个上下文工厂,以某种方式缓存上下文,例如

 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应用程序,那么在单个页面范围之外使用它会更为棘手,但您可以创建上下文的会话缓存,如果在一段时间内未使用,也可以让对象定期处理它们。此外,这段代码将有一个竞争条件,所以你需要处理它,但这是基本的想法。这本质上类似于连接池的工作方式

我不想让我的上下文在类中打开而在类的处置中关闭?为什么不呢?如果你真的不想这样做,你可以要求调用者提供和处理上下文。事实上,你的第一句话——你不只是为每个方法创建和销毁上下文——足够清楚,可以为我提供解决方案。哈哈!好吧,简单的答案似乎很简单,我想在任何情况下创建上下文的开销一定有我不知道的地方。。。但不管怎样,我很高兴它成功了。