Как использовать Autofac в проекте библиотеки классов? - PullRequest
15 голосов
/ 01 февраля 2011

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

private INewsRepository newsRepository;

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

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

Ответы [ 3 ]

22 голосов
/ 01 февраля 2011

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

.

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

Это хорошее начало для разработки сервиса в режиме DI Friendly с сохранением независимости от контейнера .

3 голосов
/ 30 марта 2013
[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>();
    }
}

Внутри библиотеки классов я создал класс «Register».Здесь настройка Autofac завершена.В моем тестовом проекте я читаю этот файл (Register.RegisterTypes) и запускаю _container.

Теперь у меня есть доступ к Разрешить все вкусности в тестируемом проекте.

2 голосов
/ 01 февраля 2011

Полагаю, это будет зависеть от того, собираетесь ли вы использовать одну и ту же сборку в нескольких хост-приложениях. Действительно ли сборка требует ссылки на 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();
...