Я написал общий тип: IDirectorySource<T> where T : IDirectoryEntry
, который я использую для управления записями Active Directory через мои объекты интерфейсов: IGroup
, IOrganizationalUnit
, IUser
.
, чтобы ямогу написать следующее:
IDirectorySource<IGroup> groups = new DirectorySource<IGroup>(); // Where IGroup implements `IDirectoryEntry`, of course.`
foreach (IGroup g in groups.ToList()) {
listView1.Items.Add(g.Name).SubItems.Add(g.Description);
}
Из методов IDirectorySource<T>.ToList()
я использую отражение, чтобы найти подходящий конструктор для параметра типа T
.Однако, поскольку T
задан тип interface , он вообще не может найти конструктор!
Конечно, у меня есть internal class Group : IGroup
, который реализует интерфейс IGroup
.Как бы я ни старался, я не могу понять, как вывести конструктор из моего интерфейса через класс реализации.
[DirectorySchemaAttribute("group")]
public interface IGroup {
}
internal class Group : IGroup {
internal Group(DirectoryEntry entry) {
NativeEntry = entry;
Domain = NativeEntry.Path;
}
// Implementing IGroup interface...
}
В методе ToList()
моей реализации интерфейса IDirectorySource<T>
Я ищу конструктор T
следующим образом:
internal class DirectorySource<T> : IDirectorySource<T> {
// Implementing properties...
// Methods implementations...
public IList<T> ToList() {
Type t = typeof(T)
// Let's assume we're always working with the IGroup interface as T here to keep it simple.
// So, my `DirectorySchema` property is already set to "group".
// My `DirectorySearcher` is already instantiated here, as I do it within the DirectorySource<T> constructor.
Searcher.Filter = string.Format("(&(objectClass={0}))", DirectorySchema)
ConstructorInfo ctor = null;
ParameterInfo[] params = null;
// This is where I get stuck for now... Please see the helper method.
GetConstructor(out ctor, out params, new Type() { DirectoryEntry });
SearchResultCollection results = null;
try {
results = Searcher.FindAll();
} catch (DirectoryServicesCOMException ex) {
// Handling exception here...
}
foreach (SearchResult entry in results)
entities.Add(ctor.Invoke(new object() { entry.GetDirectoryEntry() }));
return entities;
}
}
private void GetConstructor(out ConstructorInfo constructor, out ParameterInfo[] parameters, Type paramsTypes) {
Type t = typeof(T);
ConstructorInfo[] ctors = t.GetConstructors(BindingFlags.CreateInstance
| BindingFlags.NonPublic
| BindingFlags.Public
| BindingFlags.InvokeMethod);
bool found = true;
foreach (ContructorInfo c in ctors) {
parameters = c.GetParameters();
if (parameters.GetLength(0) == paramsTypes.GetLength(0)) {
for (int index = 0; index < parameters.GetLength(0); ++index) {
if (!(parameters[index].GetType() is paramsTypes[index].GetType()))
found = false;
}
if (found) {
constructor = c;
return;
}
}
}
// Processing constructor not found message here...
}
Моя проблема в том, что T
всегда будет interface
, поэтому он никогда не найдет конструктор.
Есть ли лучший способ, чем перебирать все мои типы сборок для реализации моего интерфейса?
Меня не волнует переписывание части моего кода, я хочу сделать это правильново-первых, чтобы мне не нужно было возвращаться снова и снова и снова.
РЕДАКТИРОВАТЬ # 1
Следуя совету Сэма, я пока пойдус IName
и Name
соглашением.Тем не менее, это я или есть какой-то способ улучшить мой код?
Спасибо!=)