微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将组件的依赖注入方法移动到 Blazor 服务器端中的单独 CS 库

如何解决将组件的依赖注入方法移动到 Blazor 服务器端中的单独 CS 库

想要在单独的 .cs 文件和/或单独的库中制作可重用的函数/方法。当然我知道怎么做,我的问题是我不知道在需要使用依赖注入元素的情况下怎么做。 例如,这是一个非常简单的获取用户属性函数

[Inject]
public UserManager<IdentityUser> UserManager { get; set; }

public async Task<string> GetUserId(string emailName)
{
    var user = await userManager.FindByNameAsync(emailName);
    if (user == null)
        return null;
    return user.Id;
}

这适用于每个 razor 文件/组件,如果 (!) 组件已初始化。如果没有,注入的服务也没有初始化并得到一个空异常错误

我不想将此代码片段重写/复制到我想使用的每个组件中,所以我想为它创建一个类或库。正确的做法应该是什么?最好的事情是,如果我可以将这些类型的函数移动到单独的类库或 Razor 类库中。

更新:

@Nkosi 提供了完美的解决方案,但我想提前考虑一下。 之前的代码示例非常小,那么如果我的自定义方法需要 2-3-4 或更多 DI 呢?例如(在 Razor 组件中):

[Inject]
public UserManager<IdentityUser> UserManager { get; set; }
[Inject]
public SignInManager<IdentityUser> SignInManager { get; init; }
[Inject]
public IJSRuntime jsRuntime { get; init; }
[Inject]
public CookieAuthenticationoptions cookieAuthenticationoptions { get; set; }
[Inject]
public IOptionsMonitor<CookieAuthenticationoptions> c_options { get; set; }


public async Task<string> GetUserWithOtherStuff(string email,string psw)
{
    cookieAuthenticationoptions = c_options.Get("schema");
    var user = await UserManager.FindByNameAsync(email);
    var valid = await SignInManager.UserManager.CheckPasswordAsync(user,psw);
    // etc..

    return something;
}

解决方法

移动到单独的类/库

public interface IUserService {
    Task<string> GetUserId(string emailName);
}

public class UserService : IUserService {
    private readonly UserManager<IdentityUser> userManager;
    
    public UserService(UserManager<IdentityUser> userManager) {
        this.userManager = userManager;
    }

    public async Task<string> GetUserId(string emailName) {
        var user = await userManager.FindByNameAsync(emailName);
        if (user == null)
            return null;
        return user.Id;
    }
}    

并在需要的地方注入封装的服务

[Inject]
public IUserService  UserService { get; set; }

确保在服务集合中注册了所有必要的依赖项。

可以通过扩展方法对需要的依赖注册进行分组

public static IServiceCollection AddUserServices(this IServiceCollection services) {
    services
        .AddScoped<IUserService,UserService>()
        .AddIdentity<.....>()
        //... add what is needed for this library library to function

    return services;
}

并在需要时调用/重用

//...

services.AddUserServices();

//...
,

小心像 UserManager 这样的常见注入。

如果它们被注入到多个其他服务中,而这些服务又被注入到同一个页面上,那么您最终可能会遇到线程异常炸毁您的页面。

例如,在市场页面中,您可能有一个服务为当前用户查找现有资金,另一个服务检查用户添加的项目,以及其他一些都依赖于了解当前用户的资金的服务身份证。

如果您只是愉快地将访问 UserManager 的自定义服务注入到许多嵌套组件中,那么您可能会像我第一次学习 Blazor 时一样感到悲伤。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。