【发布时间】:2011-03-05 02:27:02
【问题描述】:
我编写了一个通用类型: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 类型,它根本找不到任何构造函数!
当然,我有一个实现IGroup 接口的internal class Group : IGroup。无论我多么努力,我都无法弄清楚如何通过我的实现类将构造函数从我的接口中取出。
[DirectorySchemaAttribute("group")]
public interface IGroup {
}
internal class Group : IGroup {
internal Group(DirectoryEntry entry) {
NativeEntry = entry;
Domain = NativeEntry.Path;
}
// Implementing IGroup interface...
}
在我的IDirectorySource<T>接口实现的ToList()方法中,查找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
按照 Sam 的建议,我现在将遵循 IName 和 Name 约定。但是,是我自己还是有什么方法可以改进我的代码?
谢谢! =)
【问题讨论】:
标签: c# generics reflection interface dependency-injection