public class Loader {
public IEnumerable<Type> AllTypes { get; set; }
private List<object> allInstances = new List<object>();
public event EventHandler<UnhandledExceptionEventArgs> LoadingError;
public void LoadFromFolder(string folder) =>
AllTypes = Directory.GetFiles(folder, "*.dll").SelectMany(f => {
IEnumerable<Type> ts;
try {
ts = Assembly.LoadFile(f).ExportedTypes;
} catch {
return Enumerable.Empty<Type>();
}
return ts;
});
public T Instance<T>() =>
Instances<T>(false, t => true).FirstOrDefault();
public IEnumerable<T> Instances<T>() =>
Instances<T>(false, t => true);
public T Instance<T>(bool createNew, Func<T, bool> filter) =>
Instances(createNew, filter).FirstOrDefault();
public IEnumerable<T> Instances<T>(bool createNew, Func<T, bool> filter) {
var bt = typeof(T);
var ii = bt.IsInterface;
return from type in AllTypes
where !type.IsInterface && !type.IsAbstract && (ii ? type.GetInterfaces().Contains(bt) : type.IsSubclassOf(bt))
let r = (T)create(type, createNew)
where filter(r)
select r;
}
private object create(Type type, bool createNew) {
var r = allInstances.FirstOrDefault(i => i.GetType() == type) ?? Activator.CreateInstance(type);
if (createNew) {
allInstances.Remove(r);
}
allInstances.Add(r);
return r;
}
}