Архитектура моего приложения - PullRequest
0 голосов
/ 12 января 2011

это, безусловно, основной вопрос для большинства из вас, но он все еще вызывает у меня головную боль, когда я думаю об этом.

У меня есть класс репозитория, который принимает имя домена для создания экземпляра:

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

Я разрываюсь на две части, потому что в моем общем подходе мне бы хотелось иметь возможность фильтровать мой запрос в службе и просить хранилище действительно извлечь данные. Но здесь, с помощью AD, я не могу открыть и закрыть свое соединение на уровне репозитория, или я теряю гибкость, и репозиторий получает все.

Все непонятно, потому что в моей голове тоже непонятно, я просто надеюсь, что кто-то покажет мне один выход из этого с ***.

Спасибо за вашу поддержку,

Ответы [ 2 ]

0 голосов
/ 12 января 2011

Я предполагаю, что есть какая-то причина, по которой вы не просто создаете и уничтожаете контекст для каждого метода, эффективность?

Я бы создал фабрику контекста, которая каким-то образом кэширует контексты, например,

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

Затем, в какой бы области вы не захотели это использовать, создайте новый экземпляр класса и используйте его для получения контекста и избавьтесь от него в конце. Если бы это было веб-приложение, было бы более хитро использовать его за пределами одной страницы, но вы могли бы создать (например) сеансовый кэш контекстов, и объект также периодически избавлялся бы от них, если не использовался в течение некоторого периода времени. время. Также этот код будет иметь состояние гонки, так что вам нужно разобраться с этим, но это основная идея. По сути, это похоже на работу пула соединений.

0 голосов
/ 12 января 2011

Что делает класс 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 чуть позже (например, другим хранилищем).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...