Как использовать Autofac в проекте библиотеки классов?

У меня есть следующая реализация:

private INewsRepository newsRepository;

public NewsService(INewsRepository newsRepository)
{
     this.newsRepository = newsRepository;
}

Эта услуга находится в отдельном проекте, чем в моем веб-проекте. Где и как я могу указать инъекцию зависимостей? Должен ли я поместить его в файл global.asax? Что делать, если эта служба используется и для моих других приложений?

Ответ 1

Вы должны ссылаться только на контейнер из корня приложения (global.asax). Это называется регистр разрешить шаблон выпуска.

Правильное использование Инъекции конструктора гарантирует, что вы можете повторно использовать класс NewsService из других приложений , не требуя, чтобы эти другие приложения использовали конкретный контейнер DI (или вообще любой).

Это хорошее начало в проектировании сервиса с помощью дружественного образа DI, но при этом агностик контейнера.

Ответ 2

Я предполагаю, что это будет зависеть от того, собираетесь ли вы использовать одну и ту же сборку в нескольких хост-приложениях. Действительно ли сборка требует ссылок на AutoFac? Я бы рекомендовал против этого, как если бы ваши требования изменились позже, у вас будет масса ненужных ссылок. Ваше хост-приложение должно контролировать сборку модульных частей, поэтому я бы оставил конфигурацию до вашего хоста (в этом случае ваше веб-приложение. Если вы хотите подтолкнуть некоторый контроль над регистрацией, вы можете создать тип, который обрабатывает вашу регистрацию, но, как я уже упоминал ранее, ваша сборка по существу связана с использованием AutoFac, например:

public static class NewsRegistration()
{
    public static void RegisterTypes(ContainerBuilder builder)
    {
        // Register your specific types here.
        builder.RegisterType<NewsService>().As<INewsService>();
    }
}

Таким образом, вы можете легко вызвать:

var builder = new ContainerBuilder();
// Register common types here?

NewsRegistration.RegisterTypes(builder);

var container = builder.Build();

Ответ 3

[TestClass]
public class LogTest 
{
    /// <summary>
    /// Test project: autofac impl.
    /// </summary>
    private readonly ContainerBuilder _builder; 
    private readonly IContainer _container;

    /// <summary>
    /// Initializes a new instance of the <see cref="LogTest" /> class.
    /// </summary>
    public LogTest()
    {
        //
        // Read autofac setup from the project we are testing
        //
        _builder = new ContainerBuilder();
        Register.RegisterTypes(_builder);
        _container = _builder.Build();

        loggingService = _container.Resolve<ILoggingService>(new NamedParameter("theType", this));
    }

    [TestMethod]
    public void DebugMsgNoExectption()
    {
        var a = _container.Resolve<IHurraService>();
        var b = a.ItsMyBirthday();

public class HurraService : IHurraService
{
    private IHurraClass _hurra;

    /// <summary>
    /// Initializes a new instance of the <see cref="HurraService" /> class.
    /// </summary>
    public HurraService(IHurraClass hurra)
    {
        _hurra = hurra;
    }

    /// <summary>
    /// It my birthday.
    /// </summary>
    public string ItsMyBirthday()
    {
        return _hurra.Hurra();
    }
}

public static class Register
{
    public static void RegisterTypes(ContainerBuilder builder)
    {
        builder.RegisterType<LoggingService>().As<ILoggingService>();
        builder.RegisterType<HurraService>().As<IHurraService>();
        builder.RegisterType<HurraClass>().As<IHurraClass>();
    }
}

Внутри библиотеки классов я создал класс "Регистрация". Здесь выполняется настройка Autofac. В моем тестовом проекте я прочитал этот файл (Register.RegisterTypes) и запустил _container.

Теперь у меня есть доступ к Разрешению всех полезных свойств внутри проекта, который я тестирую.