跟踪Dictionary <tkey,tvalue =“”>中包含的对象的更改并相应地更改其TKey </tkey,>

时间:2010-11-17 17:18:39

标签: c# vb.net dictionary inotifypropertychanged

我正在编写一个类库来与域Active Directory进行交互。在我的对象模型中,我有以下内容:

  1. 域;
  2. 组织单位;
  3. 组;
  4. 用户。
  5. 在我的Domain对象中,我有一个Entries属性和一个Add()方法。

    public class Domain {
        // The ReadOnlyDictionary<TKey, TValue> is a custom wrapper over an IDictionary.
        public ReadOnlyDictionary<string, IDirectoryEntry> Entries { get; }
    
        public void Add(IDirectoryEntry entry) {
            Entries.Add(entry.Name, entry);
        }
    }
    

    现在,让我们假设我有以下代码测试进行更改。

    [Test()]
    public void ChangeTesting {
        Domain domain = new Domain("LDAP://...");
        Group g = new Group("groupName");
    
        domain.Add(g);
    
        g.Name = "ChangedName";
    
        Assert.IsTrue(domain.ContainsKey("ChangedName"));
    }
    

    为了您的信息,我实施了INotifyPropertyChanged界面来缓解我的生活,但我似乎找不到让它按照我想要的方式工作的方法。也许我不是以某种方式正确行事,至于不同方法的位置,我不知道。

    如何让Domain了解其Entries中的某个更改,以便TKey值也发生变化? < / p>

    这是需要的,因为有人可能会添加一个条目,更改其名称,同时在条目中添加一个具有“旧”名称的新条目,并导致冲突等。最后,导致测试失败。但是我想让它像实际一样通过。

    还有其他更好的方法或解决方法吗?

1 个答案:

答案 0 :(得分:1)

这是一个真的糟糕的黑客攻击,它可能在多线程环境中惨遭失败,但这里有:

private Dictionary<IDirectoryEntry, PropertyChangedEventHandler> eventHandlers =
    new Dictionary<IDirectoryEntry, PropertyChangedEventHandler>();

public void Add(IDirectoryEntry entry) {
    string oldName = entry.Name;

    PropertyChangedEventHandler h;
    h = (o, args) => {
        if (args.PropertyName == "Name" &&
                entry.Name != oldName &&
                Entries[oldName] == entry) {
            entry.PropertyChanged -= h;
            Entries.Remove(oldName);
            Add(entry);
        }
    };

    eventHandlers[entry] = h;
    entry.PropertyChanged += h;

    Entries.Add(entry.Name, entry);
}

public void Remove(IDirectoryEntry entry) {
    if (Entries[entry.Name] == entry) {
        Entries.Remove(entry.Name);
        eventHandlers.Remove(entry);
    }
}

如果您希望并发活动,您可能希望在匿名方法中为每个处理程序 AND 添加lock。 (这可能意味着从一个线程中删除一个条目并更改另一个条目的名称!)