Создал текстовый проект консольный. Подтянул 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);
}
}
и судя по отладке нужные обьекты есть в контейнере.
Нет, не резолвит. Хотя вот они в контейнере.
Есть разница между получением сборок через 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 компилятор найдет первую ссылку на нее.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
подскажите у меня есть таблица в ней числа, мне надо перенести с этой таблицы в другую 2 значения с битовой маской? непонимаю я в них? с примера...
Всем привет, работаю с cs cart и имею такой запрос
Помогите, пожалуйста)Вроде нет проблем, поля одинаковые, но не хочет связыватьПоследовательность правильная
Ошибка при создании пользователя