Можно ли отключить автоматическое создание экземпляров UnityContainer?

UnityContainer.Resolve() будет создавать экземпляры классов, которые не были явно зарегистрированы посредством отражения, что позволяет делать такие вещи:

using System;
using Microsoft.Practices.Unity;

namespace ConsoleApplication2
{
    public class Foo
    {
        public void SayHello()
        {
            Console.WriteLine("Hello");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            var foo = container.Resolve<Foo>();
            foo.SayHello();
        }
    }
}

Мой вопрос в том, что это поведение можно отключить, если я захочу, чтобы класс не разрешался автоматически (либо с возбуждением исключения, либо с возвратом нуля?)


person Mike Nunan    schedule 26.05.2011    source источник


Ответы (3)


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

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

person Chris Tavares    schedule 26.05.2011
comment
Спасибо за ответы, ребята. Крис, который указывает мне правильное направление, большое спасибо. - person Mike Nunan; 28.05.2011
comment
Пример такого расширения можно найти здесь: stackoverflow.com/a/31421366/1988326. - person mark.monteiro; 04.06.2020

Вы можете использовать Resolve<>(), передав регистрационное имя, как описано здесь. Поэтому попробуйте передать регистрационное имя, которого не существует, и посмотрите, что произойдет. Надеюсь, это обойдет логику отражения Unity и вернет объект NULL.

person Jason Evans    schedule 26.05.2011
comment
Нет, логика автоматического создания осталась прежней — имя — это просто ключ к внутреннему списку регистраций. Если он ничего не находит в списке, срабатывает значение по умолчанию. - person Chris Tavares; 26.05.2011
comment
Спасибо за разъяснение этого. Я сохраню этот ответ здесь на случай, если кому-то еще нужно будет об этом узнать. - person Jason Evans; 31.05.2011

Подумайте об использовании интерфейсов. Что-то вроде этого:

interface IFoo{...}
class Foo:IFoo{...}
// ...
var foo = container.Resolve<IFoo>(); // Exception here
person Alexus1024    schedule 25.04.2013