跟踪包含在Dictionary中的对象的变化。并相应地更改其 TKey

发布于 2024-10-02 19:14:36 字数 1121 浏览 0 评论 0原文

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

  1. 域;
  2. 组织单位;
  3. 团体;
  4. 用户。

在我的 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 值也发生更改?

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

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

I am writing a class library to interact with a domain Active Directory. In my object model, I have the following:

  1. Domain;
  2. Organizational Unit;
  3. Group;
  4. User.

In my Domain object, I have an Entries property and an Add() method.

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

Now, let's suppose I have the following code testing for changes.

[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"));
}

For your information, I implemented the INotifyPropertyChanged interface to ease my life, but I don't seem to find a way to make it work the way I want. Perhaps am I not doing things right somehow, as for the location of different methods, I don't know.

How can I make my Domain aware of a change that occured within one of its Entries, so that the TKey value is also changed?

That is wanted because one could possibly add an entry, change its name meanwhile adding a new entry with the "old" name of the actual within entry, and cause a conflict, etc. In the end, causing the test to fail. But I'd like to make it pass like it actually is.

Is there another better approach or workaround?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三生池水覆流年 2024-10-09 19:14:36

这是一个非常糟糕的黑客行为,在多线程环境中它可能会惨败,但这里是:

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。 (这可能意味着从一个线程中删除一个条目并从另一个线程中更改条目的名称!)

This is a really bad hack, and it will probably fail miserably in a multithreaded environment, but here goes:

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

You will probably want to lock on something for each handler AND inside the anonymous method if you expect concurrent activity. (This could mean removing an entry from one thread and changing the name of an entry from another!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文