Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolve dependency Injection for abstract class in .Net core 2.0

I am using .net Core 2.0.

I have one MemberInfo class which will inherit the Member Abstract class. Need to resolve the Dependency in StartUp.cs file.

public class MemberInfo : Member
{
    public MemberInfo()
    {

    }
}
public abstract class Member: IMemberDetails
{
    public DateTime currentDate = DateTime.Now;;
} 

In startup.cs file

public void ConfigureServices(IServiceCollection services)
  {   
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddScoped<IMemberDetails, Member>();
services.AddScoped<Member, MemberInfo >();
}

I am getting exception message as

InvalidOperationException: Unable to resolve service for type 'MemberIfo' while attempting to activate 'ProcessData'.

like image 589
Maheboob Subhani Avatar asked Jul 25 '19 09:07

Maheboob Subhani


People also ask

Can we use dependency injection in abstract class?

Any concrete class inheriting the abstract class should be instantiable with a constructor (if not abstract itself of course). But use of constructor is prohibited by Spring because any class that we instantiate this way cannot be taken in charge by Spring's automated dependency injection.

How can dependency injection be resolved?

Resolve dependencies using IServiceProvider You can use the IServiceCollection interface to create a dependency injection container. Once the container has been created, the IServiceCollection instance is composed into an IServiceProvider instance. You can use this instance to resolve services.

What is IServiceCollection in .NET Core?

AddScoped(IServiceCollection, Type, Type) Adds a scoped service of the type specified in serviceType with an implementation of the type specified in implementationType to the specified IServiceCollection.


2 Answers

Your ProcessData-Class can't find a MemberInfo because you added MemberInfo as representation for the Member-class. If you want to access the type MemberInfo directly you need to do services.AddScoped<MemberInfo, MemberInfo >(); or shorter services.AddScoped<MemberInfo>();.

If you only need the abstract definition you should request the abstract class Member, not the concrete implementation MemberInfo in your ProcessData-class. To make the differentiation between definition and implementation more clear you might want to add an interface as was pointed out in this answer.

If you want to have both types available pointing to the same implementation but don't want to have multiple instances in the same scope you can do something like this:

services.AddScoped<MemberInfo>();
services.AddScoped<Member>((serviceProvider) => serviceProvider.GetRequiredService<MemberInfo>());
like image 73
Christoph Sonntag Avatar answered Sep 29 '22 08:09

Christoph Sonntag


First one you have a syntax error you injecting MemberInfo but the log showing MemberIfo that might be the problem, also it is better to do injections with Interface maybe your Member class in services.AddScoped<Member, MemberInfo >(); it Interface it is hard to tell from here.

Also DependencyInjections work only in Controller class. Your class doe's not inherit from a Controller class and do not use the key word "Controller". Your code:

public class MemberInfo : Member
{
    public MemberInfo()
    {

    }
}
public abstract class Member: IMemberDetails
{
    public DateTime currentDate = DateTime.Now;;
}

How dependency injection actually should look:

public class MemberInfoController : Controller
{
      IMemberDetails details;
      public MemberInfo(IMemberDetails det)
      {
          details = det;
      }
}
// further code

Also a few notes

If you wont to use injected dependency outside of controller you can just pass it with a function.

Like this

// Here was DependencyInjection

public IActionResult res()
{
   MyClass class = new MyClass();
   class.SomeFunc(details);
}
like image 45
Anton Polchenko Avatar answered Sep 29 '22 08:09

Anton Polchenko