Reputation: 713
I'm developing a Blazor app and somewhere I'm implementing an interface:
public class UserData : IUserData
{
private readonly ISqlDataAccess _db;
public UserData(ISqlDataAccess db)
{
_db = db;
}
public void SomeFunction ()
{
...
}
}
public interface IUserData
{
void SomeFunction();
}
While on .razor
I can do: @inject IUserData UserData;
and ((UserData)UserData).SomeFunction();
; I'm failing to discover how to do it on .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();
Edit
So now, when I'm calling the method from the .cs file
, the app freezes; it doesn't throw an error and I am able to refresh the page, so it seems it's stuck on the call to the db; but if I call it from the .razor
it works flawlessy.
.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;
}
...
}
.razor
@inject IUserData _db;
@code {
private List<UserModel> users;
...
protected override async Task OnInitializedAsync()
{
users = await _db.GetUsers();
}
...
UserData
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 { });
}
...
}
IUserData
public interface IUserData
{
Task<List<UserModel>> GetUsers();
...
}
Edit2 It turns out I was missing an await when calling Validate() service, and thus not running it asynchronous.
Upvotes: 0
Views: 1244
Reputation: 23
In Startup.cs
you can register your interface and implementation;
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IUserData, Userdata>();
}
Then you can use the interface in a class:
public class TestClass{
private IUserData _userData;
public TestClass(IUserData userdata){
_userData = userdata;
}
}
Upvotes: 2
Reputation: 769
At some point in the program, you need to setup dependency injection. This is most common to do in the ConfigureServices
method in Startup.cs
by convention.
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>();
}
}
You need to pass the ISqlDataAccess
to the constructor of the UserData
but you had it covered already.
public class UserData : IUserData
{
private readonly ISqlDataAccess _db;
public UserData(ISqlDataAccess db)
{
_db = db;
}
//...
}
Then you need to pass your IUserData
to your objects via constructors:
public class ClassWithIUserDataDependency {
private IUserData _userData;
public ClassWithIUserDataDependency (IUserData userData) {
_userData = userData;
}
//rest of the class
}
One note: You would need to pass IUserData to all dependency classes. Based on the name, this looks like a POCO object (If it is not, don't mind this comment) If this is a POCO class, or anything representing a DTO or Data, then it is better to separate db from it and allow users to just new
it. If it is not, you may want to change its name.
Upvotes: 3