Поддержка времени компиляции для Autofac

Мы исследуем контейнеры внедрения зависимостей для нашего проекта. Сейчас выбираем между Autofac и Castle Windsor. Есть кое-что, что очень важно для нас: строго тип регистрации для Autofac.

Пример:

public interface ITestAutofac
{        
}

public class NotDerivedFrom
{        
}

Для Виндзора я могу написать что-то вроде этого -

var cont = new WindsorContainer();

cont.Register(Component
    .For<ITestAutofac>().ImplementedBy<NotDerivedFrom>());

И это будет неудачно во время компиляции. Resharper может легко помочь в этом.

Для Autofac я могу написать так -

builder.Register(c => new NotDerivedFrom()).As<ITestAutofac>();

var form = container.Resolve<ICustomForm>();

И он выйдет из строя во время выполнения.

Как я могу зарегистрировать типы в Autofac с проверкой времени компиляции?


person evgeniy.chepurnykh    schedule 18.12.2012    source источник


Ответы (2)


builder.Register<NotDerivedFrom>().As<ITestAutofac>()

С Autofac это не удастся во время выполнения, но это произойдет, когда вы вызовете builder.Build(), что не так уж и плохо, если подумать об этом. Я согласен, это не так приятно, как иметь поддержку во время компиляции, но вы можете найти модульный тест, который вызывает builder.Build(). Не забывайте, что большинство ошибок конфигурации DI все равно не могут быть обнаружены компилятором, и вам нужен ваш контейнер, поддающаяся проверке конфигурация и несколько модульных тестов, чтобы найти все ошибки конфигурации.

Как я могу зарегистрировать типы в Autofac с проверкой времени компиляции?

Если вы хотите, вы можете написать простой метод расширения, который добавляет проверку времени компиляции:

public static void Register<TService, TImplementation>(
    this ContainerBuilder builder)
    // Note the generic type constraints here
    where TImplementation: class, TService
    where TService: class
{
    builder.Register<TImplementation>().As<TService>();
}

Это позволяет вам выполнить первоначальную регистрацию следующим образом:

build.Register<ITestAutofac, NotDerivedFrom>();

Что не удастся во время компиляции.

person Steven    schedule 18.12.2012
comment
Хорошо, спасибо за ваш ответ. Я хотел сказать, что поддержка времени компиляции позволяет избежать глупых ошибок и, например, замок и единство имеют такую ​​возможность. Расширение — это костыль в проектировании, поэтому меня интересовало что-то нативное в автофаке. - person evgeniy.chepurnykh; 18.12.2012
comment
С Autofac вы получите эту поддержку во время выполнения. Конфигурация проверяется в тот момент, когда вы вызываете builder.Build(). - person Steven; 03.04.2013

Основываясь на ответе Стивена, я обновил метод расширения, чтобы вернуть IRegistrationBuilder, чтобы можно было продолжить работу с регистрацией (установка области действия и т. д.):

public static class ContainerBuilderExtensions
{
  public static IRegistrationBuilder<TImplementation, ConcreteReflectionActivatorData, SingleRegistrationStyle>
    RegisterType<TService, TImplementation>(this ContainerBuilder builder)
    where TImplementation : class, TService
    where TService : class
  {
    return builder.RegisterType<TImplementation>().As<TService>();
  }
}

Пример использования:

var builder = new ContainerBuilder();
builder.RegisterType<IMyFactory, MyFactory>().SingleInstance();
var container = builder.Build();
person Lasse Christiansen    schedule 01.02.2015