ASP. NET Core 3.x - Access Io C Контейнер - PullRequest
2 голосов
/ 19 февраля 2020

В ASP. NET Core 3.x, использование контейнеров Io C, таких как Autofa c, изменилось. Вместо того, чтобы возвращать какой-либо экземпляр адаптера в ConfigureServices, мы должны использовать новый метод ConfigureContainer.

Мой вопрос: как я могу получить доступ к экземпляру Autofa c IContainer в методе Configure? Я пытался вызвать containerBuilder.Build в пределах ConfigureContainer, чтобы получить ссылку на экземпляр контейнера, но затем я получаю исключение, что контейнер может быть собран только один раз.

Я хорошо знаю, что в обычных случаях использования , не нужно проходить вокруг контейнера (шаблон службы локатора и т. д. c .....). Однако в этом особом случае мы используем промежуточное программное обеспечение, которое разрешает типы обработчиков команд и событий, и оно основано на Autofa c. Ему нужен экземпляр контейнера.

Есть ли шанс сослаться на экземпляр IContainer после того, как он был построен фреймворком?

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Чтобы получить экземпляр IContainer, вы можете воспользоваться решением из документации autofa c ( ссылка ):

// Configure is where you add middleware. This is called after
// ConfigureContainer. You can use IApplicationBuilder.ApplicationServices   
// here if you need to resolve things from the container.   
public void Configure(IApplicationBuilder app,
                      ILoggerFactory loggerFactory)   
{
    // If, for some reason, you need a reference to the built container, you
    // can use the convenience extension method GetAutofacRoot.
    this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();

    loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
    app.UseMvc();   
}

GetAutofacRoot(); в методе расширения в Autofac.Extensions.DependencyInjection.

Таким образом, чтобы сохранить ссылку на приведенный IContainer, вы можете написать:

IContainer container = (IContainer)app.ApplicationServices.GetAutofacRoot();

Это приведение действителен потому что IContainer : ILifetimeScope

0 голосов
/ 19 февраля 2020

Если вам действительно нужна зависимость от контейнера, вы должны добавить зависимость на ILifetimeScope, а затем разрешить из этой области.

public class FooMiddleware
{
    public FooMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    private readonly RequestDelegate _next;


    public async Task InvokeAsync(HttpContext context, ILifetimeScope scope)
    {
        scope.Resolve<Foo>(); 
        await this._next(context);
    }
}
...