Может ли Autofac сделать автоматическое самосвязывание? - PullRequest
10 голосов
/ 09 июля 2009

Я знаю, что некоторые структуры DI поддерживают это (например, Ninject ), но я специально хочу знать, возможно ли это с Autofac .

Я хочу иметь возможность запросить у контейнера Autofac конкретный класс и получить экземпляр со всеми соответствующими зависимостями конструктора, , даже не зарегистрировав этот конкретный класс. Т.е., если я никогда не свяжу его в явном виде автоматически привязывает конкретный класс к себе, как если бы я позвонил builder.Register<MyClass>();

Хорошим примером того, когда это будет полезно, являются ViewModels. В MVVM расслоение таково, что только View зависит от ViewModel, и это происходит через свободную типизацию, и вы все равно не тестируете модульно View. Таким образом, нет необходимости макетировать ViewModel для тестов - и, следовательно, нет причин иметь интерфейс для каждой ViewModel. Таким образом, в этом случае обычный шаблон DI «зарегистрировать этот интерфейс для разрешения этого класса» является ненужной сложностью. Явное самообязание, такое как builder.Register<MyClass>();, также кажется ненужным шагом при работе с чем-то таким простым, как конкретный класс.

Мне известен пример регистрации на основе отражений в документах Autofac, но мне это тоже не по вкусу. Я не хочу сложности (и медлительности) регистрации каждого возможного класса заранее; Я хочу, чтобы рамки давали мне то, что мне нужно, когда мне это нужно. Соглашение о конфигурации и все такое.

Есть ли способ настроить Autofac, чтобы он мог сказать: «О, это конкретный тип, и никто еще не зарегистрировал его, поэтому я просто буду вести себя так, как будто он был зарегистрирован с настройками по умолчанию»?

Ответы [ 2 ]

14 голосов
/ 20 июля 2009
builder.RegisterTypesMatching(type => type.IsClass)

Если вы посмотрите на источник , вы увидите, что RegisterTypesMatching (и RegisterTypesFromAssembly) НЕ ДЕЛАЕТ НИКАКОГО ОТРАЖЕНИЯ. В этом случае все, что делает Autofac, - это регистрация правила, которое принимает тип или нет. В моем примере выше я принимаю любой тип, который является классом.

В случае RegisterTypesFromAssembly Autofac регистрирует правило, которое гласит: «Если тип, который вы пытаетесь разрешить, имеет Assembly == указанную сборку, то я дам вам экземпляр».

Итак:

  1. отражение типа не выполняется во время регистрации
  2. любой тип, соответствующий критерию, будет разрешен

По сравнению с прямой регистрацией конкретных типов, это будет иметь перфомент во время разрешения, так как Autofac должен будет выяснить, например, Требования к конструктору. Тем не менее, если вы используете область экземпляра по умолчанию, которая является одноэлементной, вы получаете удар только при первом разрешении этого типа. В следующий раз он будет использовать уже созданный экземпляр singleton.

Обновление: в Autofac 2 есть лучший способ сделать контейнер способным разрешать что угодно. Это включает AnyConcreteTypeNotAlreadyRegistered источник регистрации .

2 голосов
/ 16 июля 2009

а как же:

builder.RegisterTypesFromAssembly(Assembly.GetExecutingAssembly());

нет размышлений, как указывает Питер Лиллевольд .

...