Don't load executor behaviors as a dep, but initialize after all services are loaded. Experimenting on services

This commit is contained in:
Kwoth
2021-07-01 23:53:06 +02:00
parent 3c82c1f919
commit 9f34f8f00f
5 changed files with 35 additions and 94 deletions

View File

@@ -355,69 +355,5 @@ namespace NadekoBot.Extensions
return msg.Content.Headers.ContentLength / 1.MB();
}
public static IEnumerable<Type> LoadFrom(this IServiceCollection collection, Assembly assembly)
{
// list of all the types which are added with this method
List<Type> addedTypes = new List<Type>();
Type[] allTypes;
try
{
// first, get all types in te assembly
allTypes = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
Log.Error(ex, "Error loading assembly types");
return Enumerable.Empty<Type>();
}
// all types which have INService implementation are services
// which are supposed to be loaded with this method
// ignore all interfaces and abstract classes
var services = new Queue<Type>(allTypes
.Where(x => x.GetInterfaces().Contains(typeof(INService))
&& !x.GetTypeInfo().IsInterface && !x.GetTypeInfo().IsAbstract
#if GLOBAL_NADEKO
&& x.GetTypeInfo().GetCustomAttribute<NoPublicBotAttribute>() is null
#endif
)
.ToArray());
// we will just return those types when we're done instantiating them
addedTypes.AddRange(services);
// get all interfaces which inherit from INService
// as we need to also add a service for each one of interfaces
// so that DI works for them too
var interfaces = new HashSet<Type>(allTypes
.Where(x => x.GetInterfaces().Contains(typeof(INService))
&& x.GetTypeInfo().IsInterface));
// keep instantiating until we've instantiated them all
while (services.Count > 0)
{
var serviceType = services.Dequeue(); //get a type i need to add
if (collection.FirstOrDefault(x => x.ServiceType == serviceType) != null) // if that type is already added, skip
continue;
//also add the same type
var interfaceType = interfaces.FirstOrDefault(x => serviceType.GetInterfaces().Contains(x));
if (interfaceType != null)
{
addedTypes.Add(interfaceType);
collection.AddSingleton(interfaceType, serviceType);
}
else
{
collection.AddSingleton(serviceType, serviceType);
}
}
return addedTypes;
}
}
}