#.net #dependency-injection #autofac
#.net #внедрение зависимостей #autofac
Вопрос:
Моя ситуация:
Мне нужно сообщить Autofac builder, чтобы загрузить сборку, на которую ссылается. К этому времени она не была загружена сама по себе, и мне это нужно до того, как загрузчик завершит настройку контейнера.
public class AppRegisterModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyModules(typeof (IPluginManager).Assembly);
}
}
Все это работает, и модуль PluginManagerRegistrationModule загружается отлично.
Сейчас меня беспокоит то, что я не могу узнать, просил ли я уже разработчика загрузить эту сборку. т. Е. Моя структура — это множество сборок с их собственными модулями регистрации, от которых они зависят. Я также вижу, что перекрестная зависимость создаст циклический цикл (хотя у меня нет перекрестных зависимостей).
В настоящее время я вижу, что это:
builder.RegisterAssemblyModules(typeof (IPluginManager).Assembly);
builder.RegisterAssemblyModules(typeof (IPluginManager).Assembly);
… запускает модули регистрации дважды, и я получаю дубликаты регистраций и дубликаты разрешенных типов (IEnumerable<> ).
Есть ли способ избежать дубликатов?
Ответ №1:
Мое решение состояло в том, чтобы предварительно загрузить все модули и сборки, прежде чем переходить к
containerBuilder
.RegisterAssemblyModules(
AppDomain.CurrentDomain.GetAssemblies());
с
private void PreConfigureRegistrationModules()
{
var parsedAssemblies = new List<Assembly>()
{
typeof (Autofac.Core.IModule).Assembly
};
do
{
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
var unparsed = loadedAssemblies
.Where(x => parsedAssemblies.Contains(x) == false)
.SelectMany(x => x.GetTypes())
.Where(x => typeof (Autofac.Core.IModule).IsAssignableFrom(x))
.Where(x => x.IsInterface == false)
.Where(x => x.IsAbstract == false)
.ToList();
var unparsedAssemblies = unparsed
.Select(x => x.Assembly)
.Distinct()
.ToList();
if (unparsed.Count == 0)
return;
unparsed.ForEach(x => Activator.CreateInstance(x));
parsedAssemblies.AddRange(unparsedAssemblies);
} while (true);
}
Затем в любом модуле регистрации, который должен предварительно загружать ссылочные сборки перед RegisterAssemblyModules, я добавляю что-то, чтобы заставить сборку загружаться
public class AppRegisterModule : Autofac.Module
{
static AppRegisterModule()
{
if (typeof (IPluginManager).Assembly == null)
throw new InvalidOperationException();
}
}
Это не дает прямого ответа на проблему дублирования, возникающую при повторном сканировании сборки, но я обхожу ее стороной.