Unity Framework IoC с конструктором по умолчанию - PullRequest
9 голосов
/ 15 сентября 2010

Я пытаюсь внедрить зависимость в мои контроллеры MVC, как это

private static void RegisterContainer(IUnityContainer container)
{            
    container
        .RegisterType<IUserService, UserService>()
        .RegisterType<IFacebookService, FacebookService>();
}

Класс UserService имеет конструктор, подобный этому ...

public UserService(): this(new UserRepository(), new FacebookService())
{
    //this a parameterless constructor... why doesnt it get picked up by unity?
}

public UserService(IUserRepository repository, IFacebookService facebook_service)
{
    Repository=repository;
    this.FacebookService=facebook_service;
}

Исключением я являюсьполучается следующее ...

Текущий тип, Repositories.IUserRepository, является интерфейсом и не может быть создан.Вам не хватает отображения типов?

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

Ответы [ 2 ]

25 голосов
/ 16 сентября 2010

Соглашение Unity по умолчанию (которое довольно четко прописано в документации) - это выбирать конструктор с наибольшим количеством параметров.Вы не можете просто сделать общее утверждение, что «это неправда, что IoC найдет самый конкретный конструктор, если вы не укажете параметры конструктора при регистрации типа, он автоматически вызовет конструктор по умолчанию».Каждая реализация контейнера может иметь и имеет разные значения по умолчанию.

В случае Unity, как я уже сказал, он выберет конструктор с наибольшим количеством параметров.Если есть два, у которых есть большинство параметров, то это будет неоднозначно и бросить.Если вы хотите что-то другое, вы должны настроить контейнер для этого.

На ваш выбор:

Поместите атрибут [InjectionConstructor] в конструктор, который вы хотите вызвать (не рекомендуется, но быстропросто).

Использование API:

container.RegisterType<UserService>(new InjectionConstructor());  

Использование конфигурации XML:

<container>
  <register type="UserService">
    <constructor />
  </register>
</container>
0 голосов
/ 15 сентября 2010

Я не могу говорить с Unity специально, но контейнеры IoC, как правило, пытаются использовать самый конкретный конструктор, который они могут найти , потому что это конструктор .

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

На ваш конкретный вопрос, согласно вашему коду:

private static void RegisterContainer(IUnityContainer container)
{            
    container
        .RegisterType<IUserService, UserService>()
        .RegisterType<IFacebookService, FacebookService>();
}

IUserRepository не зарегистрирован. Добавьте строку как

.RegisterType<IUserRepository, UserRepository>()
...