通过中间件的有条件依赖注入。

发布于 2025-02-09 21:10:32 字数 508 浏览 1 评论 0原文

是否可以根据传递给其的道具将服务的2种不同的实现并将特定的实现注入组件中?

我试图找到一个解决方案,而我所能找到的就是将所需的服务从我不想做的构造函数中拉出。我在API控制器中做了类似的操作,从本质上讲,在注入服务层并根据请求参数注入正确的服务实现之前,该请求将截取。

编辑:

从本质上讲,在启动期间,我希望能够注入相同接口服务的2个实现。

builder.Services.AddScoped<IEmployeeService,EmployeeServiceA>();
builder.Services.AddScoped<IEmployeeService,EmployeeServiceB>();

然后,在我的组件中,我会做类似的事情:

@inject IEmployeeService _employeeService;

将实际的实现注入到组件中,该组件基于将参数发送到组件中,该组件将被中型磨损拦截。

Is it possible to have 2 different implementations of a service and inject a specific implementation into a component based on the props passed to it?

I have tried to find a solution and all I could find is pulling the desired service out of the services provider in the constructor which I don't want to do. I have done something similar in an API Controller which essentially would intercept the request before the service layer was injected and inject the correct service implementation depending on the request parameters.

Edit:

Essentially during startup I want to be able to inject 2 implementations of the same interface service.

builder.Services.AddScoped<IEmployeeService,EmployeeServiceA>();
builder.Services.AddScoped<IEmployeeService,EmployeeServiceB>();

Then in my component I would do something like:

@inject IEmployeeService _employeeService;

With the actual implementation being injected into the component being decided based off of parameters being sent into the component which would be intercepted by middle wear.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぃ双果 2025-02-16 21:10:32

您需要通过在提供商上注入iserviceProvider并调用getService来手动从ServiceProvider获得正确的服务。

注意:不建议对普通组件注射使用,因为您需要在使用服务时要谨慎:您可以在初始化之前尝试访问它。在下面的示例中,它在on Initialized中不可用。

这是简单通知服务的示例。

接口:

public interface INotificationService
{
    public event EventHandler? Changed;
    public void NotifyChanged(object? sender);
}

两个类:

public class WeatherForecastNotificationService
    : INotificationService
{
    public event EventHandler? Changed;
    public void NotifyChanged(object? sender)
        => this.Changed?.Invoke(sender, EventArgs.Empty);
}
public class WeatherReportNotificationService
    : INotificationService
{
    public event EventHandler? Changed;

    public void NotifyChanged(object? sender)
        => this.Changed?.Invoke(sender, EventArgs.Empty);
}

注册为(范围)服务:

builder.Services.AddScoped<WeatherForecastNotificationService>();
builder.Services.AddScoped<WeatherReportNotificationService>();

获取服务的组件-ServiceTestComponent.Razor:

@inject IServiceProvider serviceProvider

<div class="bg-info p-2 m-2">
    <h3>ServiceTestComponent</h3>
    <div class="p-3">
        Type: @message
    </div>
</div>

@code {
    [Parameter] public object? Record { get; set; }

    private INotificationService notificationService = default!;
    private string message = string.Empty;

    protected override void OnParametersSet()
    {
        if (this.Record is WeatherForecast)
        {
            var service = serviceProvider.GetService<WeatherForecastNotificationService>();
            if (service is not null)
                notificationService = service as INotificationService;
        }
        else
        {
            var service = serviceProvider.GetService<WeatherReportNotificationService>();
            if (service is not null)
                notificationService = service as INotificationService;
        }

        // simple bit of code to demo what actual service we have
        if (notificationService is not null)
            message = notificationService.GetType().Name;
    }
}

和一个测试页面:

@page "/"
@page "/Index"

<h1>Hello</h1>
<ServiceTestComponent Record=this.record />
<div>
    <button class="btn btn-primary" @onclick=ChangeType>Change Type</button>
</div>
@code
{
    private object record = new WeatherForecast();

    private void ChangeType()
    {
        if (record is WeatherForecast)
            record = new WeatherReport();

        else
            record = new WeatherForecast();
    }
}

You need to manually get the correct service from the ServiceProvider by injecting the IServiceProvider and calling GetService on the provider.

Note: This is not recommended for normal component injection because you need to be careful about when you use the service: you may try and access it before you have initialized it. In the example below it's not available in OnInitialized.

Here's an example for a simple notification service.

An interface:

public interface INotificationService
{
    public event EventHandler? Changed;
    public void NotifyChanged(object? sender);
}

Two classes:

public class WeatherForecastNotificationService
    : INotificationService
{
    public event EventHandler? Changed;
    public void NotifyChanged(object? sender)
        => this.Changed?.Invoke(sender, EventArgs.Empty);
}
public class WeatherReportNotificationService
    : INotificationService
{
    public event EventHandler? Changed;

    public void NotifyChanged(object? sender)
        => this.Changed?.Invoke(sender, EventArgs.Empty);
}

Registered as (scoped) services:

builder.Services.AddScoped<WeatherForecastNotificationService>();
builder.Services.AddScoped<WeatherReportNotificationService>();

A component to get the services - ServiceTestComponent.razor:

@inject IServiceProvider serviceProvider

<div class="bg-info p-2 m-2">
    <h3>ServiceTestComponent</h3>
    <div class="p-3">
        Type: @message
    </div>
</div>

@code {
    [Parameter] public object? Record { get; set; }

    private INotificationService notificationService = default!;
    private string message = string.Empty;

    protected override void OnParametersSet()
    {
        if (this.Record is WeatherForecast)
        {
            var service = serviceProvider.GetService<WeatherForecastNotificationService>();
            if (service is not null)
                notificationService = service as INotificationService;
        }
        else
        {
            var service = serviceProvider.GetService<WeatherReportNotificationService>();
            if (service is not null)
                notificationService = service as INotificationService;
        }

        // simple bit of code to demo what actual service we have
        if (notificationService is not null)
            message = notificationService.GetType().Name;
    }
}

And a test page:

@page "/"
@page "/Index"

<h1>Hello</h1>
<ServiceTestComponent Record=this.record />
<div>
    <button class="btn btn-primary" @onclick=ChangeType>Change Type</button>
</div>
@code
{
    private object record = new WeatherForecast();

    private void ChangeType()
    {
        if (record is WeatherForecast)
            record = new WeatherReport();

        else
            record = new WeatherForecast();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文