В настоящее время я пытаюсь создать универсальную фабрику экземпляров, для которой в качестве универсального параметра используется интерфейс (применяется в конструкторе), а затем позволяет получить экземпляры объектов, реализующие этот интерфейс, из всех типов во всех загруженных сборках.
Текущая реализация выглядит следующим образом:
public class InstantiationFactory<T>
{
protected Type Type { get; set; }
public InstantiationFactory()
{
this.Type = typeof(T);
if (!this.Type.IsInterface)
{
// is there a more descriptive exception to throw?
throw new ArgumentException(/* Crafty message */);
}
}
public IEnumerable<Type> GetLoadedTypes()
{
// this line of code found in other stack overflow questions
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(/* lambda to identify instantiable types which implement this interface */);
return types;
}
public IEnumerable<T> GetImplementations(IEnumerable<Type> types)
{
var implementations = types.Where(/* lambda to identify instantiable types which implement this interface */
.Select(x => CreateInstance(x));
return implementations;
}
public IEnumerable<T> GetLoadedImplementations()
{
var loadedTypes = GetLoadedTypes();
var implementations = GetImplementations(loadedTypes);
return implementations;
}
private T CreateInstance(Type type)
{
T instance = default(T);
var constructor = type.GetConstructor(Type.EmptyTypes);
if (/* valid to instantiate test */)
{
object constructed = constructor.Invoke(null);
instance = (T)constructed;
}
return instance;
}
}
Мне кажется полезным, чтобы моя функция CreateInstance(Type)
была реализована как метод расширения, чтобы я мог использовать ее позже и упростить код моей фабрики, но я не могу понять, как вернуть строго типизированное значение из этого метод расширения.
Я понимаю, что могу просто вернуть объект:
public static class TypeExtensions
{
public object CreateInstance(this Type type)
{
var constructor = type.GetConstructor(Type.EmptyTypes);
return /* valid to instantiate test */ ? constructor.Invoke(null) : null;
}
}
Возможно ли, чтобы метод расширения создавал подпись для каждого экземпляра типа, который он расширяет?
Мой идеальный код был бы таким, чтобы избежать необходимости приводить результат вызова к CreateInstance()
:
Type type = typeof(MyParameterlessConstructorImplementingType);
MyParameterlessConstructorImplementingType usable = type.CreateInstance();