首页 > 解决方案 > 使用依赖注入在类上实现接口

问题描述

我正在开发一个 Blazor 应用程序,并在某个地方实现了一个接口:

public class UserData : IUserData
{
    private readonly ISqlDataAccess _db;

    public UserData(ISqlDataAccess db)
    {
        _db = db;
    }

    public void SomeFunction ()
    {
        ...
    }
}
public interface IUserData
{
    void SomeFunction();
}

.razor我可以做的时候:@inject IUserData UserData;((UserData)UserData).SomeFunction();; 我无法发现如何在.cs file.

//There is no such constructor and If I create a new one, then I won't get the _db dependecy injection
IUserData userDate = new UserData();
userDate.SomeFunction();

编辑

所以现在,当我从 调用方法时.cs file,应用程序冻结;它不会抛出错误,我可以刷新页面,所以它似乎卡在对数据库的调用上;但如果我从它那里调用它,.razor它就完美无缺。

。CS

public AccountService(IUserData userData)
{
    _userData = userData;
}
...
public async Task<bool> Validate(string userId, string password)
{
    ...
    try
    {
        List<UserModel> users = new List<UserModel<();
        users = await _userData.GetUsers();
        //NEVER GETS HERE
        return true;
    }
    catch (Exception ex)
    {
         return false;
    }
    ...
}

。剃刀

@inject IUserData _db;

@code {
    private List<UserModel> users;
    ...
    protected override async Task OnInitializedAsync()
    {
        users = await _db.GetUsers();
    }
    ...

用户数据

    public class UserData : IUserData
    {
        private readonly ISqlDataAccess _db;

        public UserData(ISqlDataAccess db)
        {
            _db = db;
        }

        public Task<List<UserModel>> GetUsers()
        {
            string sql = "Select *from dbo.Users";
            return _db.LoadData<UserModel, dynamic>(sql, new { });
    }
    ...
}

用户数据

    public interface IUserData
    {
        Task<List<UserModel>> GetUsers();
        ...
    }

Edit2 原来我在调用 Validate() 服务时错过了等待,因此没有异步运行它。

标签: c#blazor

解决方案


在程序的某个时刻,您需要设置依赖注入。ConfigureServices这是在约定俗成的方法中最常见的做法Startup.cs

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
           .SetBasePath(env.ContentRootPath)
           .AddJsonConfigurationProvider("appsettings.json", optional: false, reloadOnChange: true)
           .AddEnvironmentVariables();
            Configuration = builder.Build();
    }
    public void ConfigureServices(IServiceCollection services)
    {
         services.AddTransient <ISqlDataAccess, SqlDataAccess>(); //Second argument is the implementation of the interface
         services.AddTransient <IUserData, UserData>();
    }
}

您需要将 传递ISqlDataAccess给 the 的构造函数,UserData但您已经涵盖了它。

public class UserData : IUserData
{
    private readonly ISqlDataAccess _db;

    public UserData(ISqlDataAccess db)
    {
        _db = db;
    }
    //...
}

然后您需要IUserData通过构造函数将您的对象传递给您的对象:

public class ClassWithIUserDataDependency {
    private IUserData _userData;
    public ClassWithIUserDataDependency (IUserData userData) {
        _userData = userData;
    }

    //rest of the class
}

注意:您需要将 IUserData 传递给所有依赖类。根据名称,这看起来像一个 POCO 对象(如果不是,请不要介意此评论)如果这是一个 POCO 类,或者任何代表 DTO 或数据的东西,那么最好将 db 从中分离并允许用户就new可以了。如果不是,您可能需要更改其名称。


推荐阅读