2017-01-24 8 views
0

Я получаю DependencyResolutionException, пытающийся использовать Autofac's parameterized instantiation для разрешения непрямой связи.Косвенная параметризованная инстанция с использованием Autofac

Предположим, у меня есть следующие классы:

public interface IMuffin {} 

public class Muffin : IMuffin 
{ 
    public Muffin(IButter butter) {} 
} 

public interface IButter {} 

public class Butter : IButter 
{ 
    public Butter(IKnife knife) {} 
} 

public interface IKnife {} 

Теперь предположим, что Я хочу IMuffin, но я хочу поставить IKnife зависимость в качестве параметра, например:

public class Breakfast 
{ 
    public Breakfast(Func<IKnife, IMuffin> muffinFactory) 
    { 
     var muffin = muffinFactory(new Knife()); 
    } 

    private class Knife : IKnife {} 
} 

Проблема заключается в том, Я получаю исключение на muffinFactory(new Knife()), жалуясь, что фабрика не может разрешить зависимость IKnife конструктора Butter, используя доступные параметры и службы. Это не имеет никакого смысла, поскольку я представил экземпляр IKnife в качестве параметра для фабрики.

Кажется, что это должно сработать. Что мне не хватает?

+0

Это [FAQ рассматривается в документации] (http://autofac.readthedocs.io/en/latest/faq/injecting-global -parameters.html). –

+0

Хорошо, я вижу, откуда они идут, но использование параметризованного экземпляра для зависимостей _direct_ связано с некоторыми «знаниями». И только один небольшой рефакторинг превращает прямую зависимость в косвенную. На самом деле это произошло в моем случае. Используя вышеприведенный пример, предположим, что 'Muffin' первоначально зависел от' IKnife' напрямую, поэтому параметризованное создание экземпляра 'Breakfast' будет работать. Когда «Масло» было учтено, «IKnife» стал косвенной зависимостью, которая сломала «Завтрак». Такое изменение может не повлиять на потребителей IMuffin. –

ответ

0

Завод в вашем примере является фабрикой для IMuffin, а ваши параметры IKnife передаются как typed parameter. Тем не менее, вашему классу Muffin не нужен экземпляр IKnife. Для этого требуется экземпляр IButter.

Экземпляр IKnife требуется классу Butter. Но параметр, который вы передали на завод, можно использовать только для создания экземпляра Muffin, и он не используется для разрешения зависимости от Muffin. Правильный тип вашего muffinFactory будет Func<IButter, IMuffin>.

Для того, чтобы ваш пример работы нужны два завода:

public class Breakfast 
{ 
    public Breakfast(Func<IKnife, IButter> butterFactory, Func<IButter, IMuffin> muffinFactory) 
    { 
     var butter = butterFactory(new Knife()); 
     var muffin = muffinFactory(butter); 
    } 

    private class Knife : IKnife { } 
} 
+0

Да, я пробовал этот подход после публикации. Поскольку Autofac может перемещаться по дереву зависимостей, похоже, он должен иметь возможность переносить указанные вами параметры для разрешения любых зависимостей на этом пути, а не только на уровне верхнего уровня. Разочарован, что я должен удержать его, чтобы получить «IKnife» на втором уровне. –

+0

Это _very намеренно не принимает параметры с верхнего уровня и передает их каждому разрешению по всему стеку. [См. FAQ.] (Http://autofac.readthedocs.io/en/latest/faq/injecting-global-parameters.html) –

+0

@TravisIllig, спасибо за ссылку - это помогает! Пожалуйста, см. Мой ответ на ваш комментарий по оригинальному вопросу. –

 Смежные вопросы

  • Нет связанных вопросов^_^