Множественный поиск Active Directory в приложении MVC3

Мое приложение MVC позволяет группе пользователей вставлять/редактировать записи в таблицу, и, поскольку я использую аутентификацию Windows, я получаю их имена samaccountname «бесплатно» и могу вставлять их в поле «Последнее обновление» в упомянутых записях.

Одно из самых важных (и часто используемых) представлений в моем приложении будет отображать списки из 50-100 записей на странице, но я не хочу отображать их имена samaccountnames. Мне нужны их более удобные отображаемые имена, которые я хочу получить из Active Directory.

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

public interface IUserInformationStore
{
  UserInformation FindBySamAccountName(string samAccountName)
}

public class ActiveDirectoryStore
{
  HashSet<UserInformation> _cache;

  public UserInformation FindBySamAccountName(string samAccountName)
  {
    // Look for samaccountname in _cache and if not found
    // retrieve information from AD with DirectorySearcher.
    // Store information in _cache and return correct user.
}

Моя проблема сейчас в том, как получить доступ к этой информации. Я думал об использовании ToSingleton от Ninject, но я подозреваю, что это может быть «процесс Singleton Per Worker». Так что, возможно, Тайник был бы лучшим местом для него. Но как лучше всего получить доступ к объекту? Статический класс со статическим свойством, которое проверяет, находится ли он уже в кеше, в противном случае инициализирует его и возвращает объект?

Или есть совершенно лучший способ решить эту проблему?


person carlsb3rg    schedule 23.02.2011    source источник
comment
Когда вы говорите о процессе Singleton Per Worker, вы имеете в виду, что хотите разделить этот кеш информации между несколькими веб-приложениями?   -  person OdeToCode    schedule 24.02.2011
comment
Моя первая реакция, когда я увидел предоставленный вами фрагмент кода и узнал, что вы используете Ninject, — использовать функцию синглтона. Но я задал вопрос только для того, чтобы уточнить, как далеко должна идти информация (между запросами? между приложениями? между серверами?).   -  person OdeToCode    schedule 24.02.2011
comment
Этот конкретный кеш будет использоваться только в одном веб-приложении, но я не уверен, являются ли синглтоны ninject единственными для каждого приложения или единственными для каждого потока, который asp.net захватывает из пула потоков.   -  person carlsb3rg    schedule 24.02.2011


Ответы (1)


В итоге я попробовал 2 решения:

1

kernel.Bind<IUserRepository>().To<ActiveDirectoryUserRepository>().InSingletonScope().WithConstructorArgument("rootPath", "LDAP://dc=tessdata,dc=no");

public static MvcHtmlString GetDisplayNameSingleton(this HtmlHelper htmlHelper, string samAccountName)
{
  var userRepository = DependencyResolver.Current.GetService<IUserRepository>();
  return new MvcHtmlString(userRepository != null ? userRepository.FindByUsername(samAccountName).DisplayName : "Ukjent");
}

2

kernel.Bind<IUserRepository>().To<ActiveDirectoryUserRepository>().WithConstructorArgument("rootPath", "LDAP://dc=tessdata,dc=no");

public static MvcHtmlString GetDisplayName(this HtmlHelper htmlHelper, string samAccountName)
{
  if (HttpRuntime.Cache["UserRepository"] == null)
  {
    var newUserRepository = DependencyResolver.Current.GetService<IUserRepository>();
    HttpRuntime.Cache.Add("UserRepository", newUserRepository, null, DateTime.MaxValue,
                                  TimeSpan.FromMinutes(20), CacheItemPriority.Default, null);
  }
  var userRepository = HttpRuntime.Cache["UserRepository"] as IUserRepository;
  return new MvcHtmlString(userRepository != null ? userRepository.FindByUsername(samAccountName).DisplayName : "Ukjent");
}

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

Однако я не уверен в лучшей практике в любом случае.

person carlsb3rg    schedule 24.02.2011