Я пытаюсь найти правильный способ применения блокировки к следующему классу.В двух словах, объект является одноэлементным, и при его создании строится переменное число меню из XML-файлов в данном каталоге.В настоящее время разрешено только чтение, поэтому блокировка не происходит (состояния MSDN считывают потоки из словаря).Но у меня также есть средство наблюдения за файловой системой, так что я могу пересоздавать меню, когда происходят изменения.Есть два словаря, в которых происходит чтение, и поэтому мне нужен способ справиться с этим.Я мог бы использовать Lock (это), но есть ли лучший способ?Итак, единственный раз, когда я хочу заморозить чтения, это когда происходит обновление (смотрите в ctor).
Вот класс для визуала:
public class XmlMenuProvider : IMenuProvider {
private readonly INavigationService navigation;
private readonly Dictionary<string, IEnumerable<MenuItem>> menus;
private readonly Dictionary<string, Dictionary<string, MenuItem>> menusLookup;
private readonly FileSystemWatcher monitor;
public XmlMenuProvider(string folderPath, INavigationService navigation)
{
this.navigation = navigation;
this.menusLookup = new Dictionary<string, Dictionary<string, MenuItem>>();
this.menus = LoadFromSourceDirectory(folderPath);
this.monitor.Changed += (o, e) => {
// TODO - Add Locking
};
}
public IEnumerable<MenuItem> GetMenuItems(string name) {
return menus[name];
}
public MenuItem FindItemByName(string menu, string name) {
return menusLookup[menu][name];
}
private Dictionary<string, IEnumerable<MenuItem>> LoadFromSourceDirectory(string folderPath) {
var menus = new Dictionary<string, IEnumerable<MenuItem>>();
foreach (var file in Directory.GetFiles(folderPath, "*.xml")) {
var root = XDocument.Load(file).Elements().First();
var name = root.Attribute("name").Value;
var lookup = new Dictionary<string, MenuItem>();
menusLookup.Add(name, lookup);
menus.Add(name, BuildMenuHiearchyFromElement(root, lookup, null));
}
return menus;
}
private IEnumerable<MenuItem> BuildMenuHiearchyFromElement(XElement element, Dictionary<string, MenuItem> lookup, MenuItem parent) {
return element.Elements("Item")
.Select(e => {
var mi = CreateMenuItemFromElement(e, lookup, parent);
lookup.Add(mi.Name, mi);
return mi;
}
).ToList();
}
private MenuItem CreateMenuItemFromElement(XElement element, Dictionary<string, MenuItem> lookup, MenuItem parent) {
var name = element.Attribute("Name").Value;
var display = element.Attribute("DisplayName").Value;
var isClickable = true;
var roles = element.Attribute("Roles").Value.Split(',');
if (roles.Length == 1 && roles.First() == string.Empty) {
roles = new string[] { };
}
var attrClick = element.Attribute("IsClickable");
if (attrClick != null) {
isClickable = bool.Parse(attrClick.Value);
}
var navigateUrl = string.Empty;
if (isClickable) {
navigateUrl = navigation.FetchDestination(name);
}
return new MenuItem(name, display, navigateUrl, isClickable, roles, x => BuildMenuHiearchyFromElement(element, lookup, x), parent);
}
}
Спасибо.*