gpt4 book ai didi

c# - ASP.NET Core 没有用 StructureMap 替换 IoC

转载 作者:行者123 更新时间:2023-11-30 22:58:28 28 4
gpt4 key购买 nike

我的应用程序基于 ASP.NET Core 2.1 和 .NET Core 2.1(从 2.2 降级)通用主机作为 Windows 服务。所以,IHostBuilder首先与其他服务和框架一起启动,然后(如果角色允许)使用 IWebHostBuilder 在顶部启动 Web 服务所有这些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 只是为了演示,我只需要'服务'

LifetimeServicecontainer.AssertConfigurationIsValid() 期间初始化我得到
inCollection是真的
inContainer是真的
inProvider是真的
IServiceProviderStructureMapServiceProvider

实际 LifetimeService执行表明
inCollection是假的
inContainer是真的
inProvider是假的
IServiceProviderServiceProviderEngineScope

我不打算将 IServiceProvider 或 IContainer 传递给构造函数,但似乎使用 IServiceProvider 而不是 IContainer 解决了依赖关系,我得到了空值。像sp.GetRequiredService<IContainer>().TryGetInstance<IPlatformService>()这样的傻事确实有效。
有一些使用 WebHost 和 Startup 类的快乐路径示例,其中注入(inject)应该正常工作。似乎与通用主机无关......有一天可能会取代 WebHost,但鲜为人知且未广泛使用。好吧,也可能是由于 .NET Core 版本降级,但可能性很小。我也曾尝试在 ConfigureServices() 期间从 IContainer 中替换 IServiceProvider 和 IServiceScopeFactory,但没有成功。我的想法是将内部容器替换或转发到 StructureMap。我可能误解了它应该如何工作......

有没有人成功地尝试“结合”通用主机和外部 IoC?

最佳答案

我已经解决了这个难题!最后,根据一个过于简化的示例(https://github.com/aspnet/Hosting/blob/master/samples/GenericHostSample/ProgramFullControl.cs),我不得不将 HostBuilder 初始化更改为

new HostBuilder()
.UseServiceProviderFactory(new StructureMapContainerFactory(workingPath))
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<LifetimeService>();
});

并介绍provider factory本身

public class StructureMapContainerFactory : IServiceProviderFactory<IContainer>
{
private readonly IWorkingPath workingPath;
// pass any dependencies to your factory
public StructureMapContainerFactory(IWorkingPath workingPath)
{
this.workingPath = workingPath;
}

public IContainer CreateBuilder(IServiceCollection services)
{
services.AddStructureMap();
return ContainerBuilder.BuildBaseContainer(services, workingPath);
}

public IServiceProvider CreateServiceProvider(IContainer containerBuilder)
{
return containerBuilder.GetInstance<IServiceProvider>();
}
}

现在内部容器被替换为 StructureMap 并且解析 LifetimeService 中的 IServiceProviderStructureMapServiceProvider 类型。

关于c# - ASP.NET Core 没有用 StructureMap 替换 IoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52985315/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com