Разрешение зависимостей Autofac

80
22 апреля 2021, 15:30

Создал текстовый проект консольный. Подтянул autofac. Собственно есть проект библиотеки с интерфейсами. Есть пара проектов библиотек, использующих эти интерфейсы. Каждая библиотека имеет класс модуля

namespace ClassLibrary2{
public class Class2Module : Module
{
    protected override void Load(ContainerBuilder builder)
    {
       builder.RegisterType<Class1>().AsImplementedInterfaces();
    }    
  }
}

где реализация такая

public class Class1 : INterface2
{
    public void PrintServiceData()
    {
        Console.WriteLine("Данные класса 2");
    }
}

Таких реализаций 3 штуки.
Создана еще одна библиотека с реализациями вида

namespace ConsoleApp2
{
public class Application
{
    protected readonly INterface2 _nterface2;
    protected readonly INterface3 _nterface3;
    protected readonly INterface4 _nterface4;
    public Application(INterface2 nterface2, INterface3 nterface3, INterface4 nterface4)
    {
        _nterface2 = nterface2;
        _nterface3 = nterface3;
        _nterface4 = nterface4;
    }
    public void Run()
    {
        _nterface2.PrintServiceData();
        _nterface3.PrintServiceData();
        _nterface4.PrintServiceData();
    }
}
}

И собственно вопрос. Все библиотеки зарегистрированы в контейнере, но при попытке запуска вылетает ошибка

DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ConsoleApp2.Application' can be invoked with the available services and parameters: Cannot resolve parameter 'ClassLibrary2.INterface2 nterface2' of constructor 'Void .ctor(ClassLibrary2.INterface2, ClassLibrary1.INterface3, ClassLibrary1.INterface4)'.

Что не так? Библиотеки регистрируются как пример с гитхаба динамически как

var builder = new ContainerBuilder();
builder.RegisterType<Application>().AsSelf();
var assemblies = Directory.GetFiles(path + "\\" + folder, "*.dll", SearchOption.TopDirectoryOnly)
    .Select(Assembly.LoadFrom);
foreach (var assembly in assemblies)
{
    var modules = assembly.GetTypes()
        .Where(p => typeof(IModule).IsAssignableFrom(p) && !p.IsAbstract)
        .Select(p => (IModule) Activator.CreateInstance(p));
    foreach (var module in modules)
    {
        builder.RegisterModule(module);
    }
}

и судя по отладке нужные обьекты есть в контейнере.

Нет, не резолвит. Хотя вот они в контейнере.

Answer 1

Есть разница между получением сборок через Assembly.LoadFrom (комментарий в оф.доках) и через Assembly.GetAssembly(typeof(INterface2)). В первом случае сборка грузится только чтение. Поэтому Autofac не может зарезолвить ни один тип из нее, а в другом сборка ищется в домене приложения (все сборки, которым можно доверять).

Собственно если ваши либы вообще никак не ссылались внутри текущего проекта задумку с динамическим подтягиванием можно было бы понять и сворганить что-нибудь такое:

var assemblies = Directory.GetFiles(Path.Combine(path, folder), "*.dll", SearchOption.TopDirectoryOnly)
    .Select(p => AppDomain.CurrentDomain.Load(new AssemblyName(Assembly.LoadFrom(p).FullName)))
    .ToArray();
builder.RegisterAssemblyModules(assemblies);

Но т.к. проекты лежат внутри, то лучше зарегистрировать их (проекты) ручками.

var assemblies = new[]
{
    Assembly.GetAssembly(typeof(INterface2)), Assembly.GetAssembly(typeof(INterface3)),
    Assembly.GetAssembly(typeof(INterface4))
};
builder.RegisterAssemblyModules(assemblies);

Есть вариант достать все загруженные сборки из домена приложения, но это способ не гарантирует что в момент регистрации в нем будут все сборки, которые должны были попасть в контейнер. Сборка попадает в домен сразу же как JIT компилятор найдет первую ссылку на нее.

READ ALSO
битовая маска mysql

битовая маска mysql

подскажите у меня есть таблица в ней числа, мне надо перенести с этой таблицы в другую 2 значения с битовой маской? непонимаю я в них? с примера...

102
Ошибка в синтаксисе Operand should contain 1 column(s)

Ошибка в синтаксисе Operand should contain 1 column(s)

Всем привет, работаю с cs cart и имею такой запрос

117
Не могу создать внешний ключ в бд

Не могу создать внешний ключ в бд

Помогите, пожалуйста)Вроде нет проблем, поля одинаковые, но не хочет связыватьПоследовательность правильная

117
ERROR 1728 (HY000): Cannot load from mysql.user. The table is probably corrupted

ERROR 1728 (HY000): Cannot load from mysql.user. The table is probably corrupted

Ошибка при создании пользователя

189