Dependency Injection in Service class

I am trying to created an error logging service to catch data errors. I am struggling to get the dbContext and the SecurityService objects in the service class.

I have tried Inject but the objects are null and apparently you can't use DI in service classes

The alternative is i pass the dbContext ans the user details as parameters but this seems pretty ineffcient from a codeing point of view.

Can anyone help?

thanks

1 Like

Hi @johnmu,
as far as i know you can only Inject in Controller based classes?!
(i am not sure...)
Thomas

Not sure what you've tried however you can do that easily with a partial class with additional constructor for the SecurityService:

In order to be able to inject other services via constructor parameters your service must be registered to e.g. in Startup.cs. For example:

public class MyService
{
     private readonly SecurityService security;

     public MyService(SecurityService security)
     {
         this.security = security;
     }
}

Then the registration:

services.AddSingleton<MyService>();

or

services.AddTransient<MyService>();

You can now inject your service in other services or controllers (also as [Inject] properties in your Blazor pages).

public partial class MyPage : ComponentBase
{
     [Inject]
     public MyService MyService { get; set; }
}
1 Like

Vladimir,

I am not able to add a xxx.custom.cs via VS, when i right click on teh service there is no option to add. How did you do this?

Atanas,

thanks I follow what you are saying but my question was how do I get an existing service to work inside another service?

My error logging service needs to use the appContext service and the Security Service but both are null when I try and access them.

thanks

John

Hey @johnmu,

You cannot add new class in Visual Studio? It’s just a partial class - nothing else.

@johnmu, I think I explained that in my reply. You need to register your service first and then inject the required services as constructor parameters. I recommend checking Microsoft's documentation about dependency injection.

If you still need help you will need to show us more details. The code of your service, how you register it, how you inject it to use it and what is null.

Atanas,

Thanks I got it to work. I put the service in the startup.custom.cs and it works.

But then I discovered that my error log wouldn’t update because I was using the same context and couldn’t get the error table to save when I had an error on the underlying table. I solved this by changing the state of the content exit entries to stateunchanged then I could call context.savechanges().

I offer this in case it’s useful for anyone else.

But now I come to the whole point of why I needed an error log. I’m am getting intermittent exceptions when I update a table. Seems to be an issue when I take a few minutes to finish editing the form and press save. If I edit quickly there’s no issue, if I take my time exception. I can’t find anything on the web about this but it seems like a deeper issue in EF or MSSQL. It appears to happen with all my tables.

Has anyone else come across this issue? Thanks John

Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithoutPropagation(Int32 commandIndex, RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable1 commandBatches, IRelationalConnection connection) at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList1 entriesToSave) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(DbContext _, Boolean acceptAllChangesOnSuccess) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess) at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess) at Microsoft.EntityFrameworkCore.DbContext.SaveChanges() at EsWlite.EcosysService.UpdateTblClient(Nullable1 clientId, TblClient tblClient)
at CallSite.Target(Closure , CallSite , Object )
at EsWlite.Pages.AClientEditComponent.Form0Submit(TblClient args)

heres the actual error:

Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See Handling Concurrency Conflicts - EF Core | Microsoft Learn for information on understanding and handling optimistic concurrency exceptions.

but no one else is using the database far less that record so something is causing this lock

As far as I know this exception means that the record you are trying to update does not exist (for some reason). Not sure why this would happen if the record actually exists in the database. You can investigate if the query sent to the database is correct - for example an item with the specified ID does exist. You can use the SQL profiler to check the queries sent to your database.