Мое приложение основано на универсальном узле ASP.NET Core 2.1 и .NET Core 2.1 (более ранней версии 2.2) в качестве службы Windows.Итак, IHostBuilder
запускается сначала с другими службами и средами, а затем (если позволяет роль) веб-служба запускается поверх, используя IWebHostBuilder
со всем этим WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().StartAsync()
.Вторичный WebHost - это другая история;он инициализирован и работает, но я еще не проверил, имеет ли замена IoC ту же проблему, что и общий хост.
На данный момент, общая инициализация хоста:
new HostBuilder().ConfigureServices((hostContext, services) =>
{
services.AddHostedService<LifetimeService>(); // Gets launched when host is up
var container = ContainerBuilder.BuildBaseContainer(services, new WorkingPath());
services.AddSingleton<IContainer>(container);
services.AddStructureMap(); // Has no effect
});
Инициализация IContainer:
public static Container BuildBaseContainer(IServiceCollection services, IWorkingPath workingPath)
{
var container = new Container();
container.Configure(config =>
{
config.Scan(scan =>
{
workingPath.OwnLoadedAssemblies.Where(asm => !asm.IsDynamic).ForEach(scan.Assembly);
scan.LookForRegistries();
scan.AddAllTypesOf<IPlatformService>();
});
config.For<IContainer>().Use(() => container);
config.Populate(services);
});
container.AssertConfigurationIsValid();
return container;
}
И проблема здесь, в конструкторе этой зарегистрированной размещенной службы (илигде-нибудь еще)
public LifetimeService(IEnumerable<IPlatformService> services,
IServiceProvider sp, IContainer c)
{
var inCollection = services.Any();
var inContainer = c.TryGetInstance<IPlatformService>() != default;
var inProvider = sp.GetRequiredService<IPlatformService>() != default;
}
ps: IServiceProvider и IContainer предназначены только для демонстрационных целей, мне нужны только 'services'
Когда LifetimeService
инициализируется во время container.AssertConfigurationIsValid()
Я получаю
inCollection
верно
inContainer
верно
inProvider
верно
IServiceProvider
равно StructureMapServiceProvider
Фактическое LifetimeService
выполнение показывает, что
inCollection
неверно
inContainer
верно
inProvider
ложно
IServiceProvider
равно ServiceProviderEngineScope
Я не планирую передавать IServiceProvider или IContainerв конструкторы, но кажется, что зависимости разрешаются с помощью IServiceProvider, а не IContainer, и я получаю нулевые значения.Глупая штука вроде sp.GetRequiredService<IContainer>().TryGetInstance<IPlatformService>()
работает.
Было несколько примеров «счастливого пути», использующих классы WebHost и Startup, где внедрение должно работать должным образом.Не кажется актуальным для универсального хоста ... который может заменить WebHost однажды, но мало известен и не широко используется.Ну, это может быть связано с понижением версии .NET Core, но это маловероятно.Я также попытался заменить IServiceProvider и IServiceScopeFactory из IContainer во время ConfigureServices () без удачи.Моя идея - заменить или переслать внутренний контейнер в StructureMap.Возможно, я неправильно понимаю, как это должно работать ...
Кто-нибудь успешно пытался "жениться" на общем хосте и внешнем IoC?