Do I really need to call Dispose() on every Principal?
Asked Answered
L

1

9

I'm doing some Active Directory work with .NET's System.DirectoryServices.AccountManagement namespace. I noticed that Principal implements IDisposable, which causes sort of a headache since everything in that namespace inherits Principal.

E.g. consider the following code to get all the users in a group:

PrincipalContext domain = new PrincipalContext(ContextType.Domain);
GroupPrincipal group = GroupPrincipal.FindByIdentity(domain, "MyGroup");
PrincipalSearchResult<Principal> users = group.GetMembers();

Every single type in that snippet implements IDisposable, including all the users returned by the search and the search result set itself.

Disposing of the domain and group objects is not a big deal (it would be easy with a using() block), but what do I do about every result? Do I really have to loop through that users collection and dispose of every one?

Laciniate answered 12/2, 2013 at 21:7 Comment(2)
FWIW, GroupPrincipal.GetMembers shows only the group being disposed. I can't find any documentation (yet) that explicitly states this contract of "member lifetime ownership": +1 because I do find this particular contract (or perhaps lack thereof), interesting. However, here is my general view on the IDisposable contract.Cringle
Here's an answer that may help: https://mcmap.net/q/534813/-does-principalsearchresult-lt-t-gt-automatically-dispose-all-elements-in-its-collectionFacetious
M
4

The IDisposable contract is just that, a contract. It's expected to be followed. They wouldn't have implemented the contract had you not "need to call Dispose"...

In reality, you can't really tell what type of object is being used by a particular instance of Principal Sometimes, you do have to dispose it, sometimes you don't. You really don't have a way of telling at runtime unless you know some of the internals of a particular implement of Principal. For example, if the underlying object in the Principle instance is a DirectoryEntry, then you should dispose it. But, you have not real way to tell at run time what that underlying object is. Even if you could, it would seem easier to simply call Dispose.

Mole answered 12/2, 2013 at 21:58 Comment(1)
Right, I know that everything needs to be disposed. I just feel like it's confusing what I'm "in charge of". My usual assumption is that if I instantiate an object I'm responsible for cleaning it up, but that obviously doesn't apply to these classes. The MSDN docs are totally unhelpful: most of their samples have no Dispose() calls at all.Laciniate

© 2022 - 2024 — McMap. All rights reserved.