Reputation: 14137
I am having a 2 controller PayerController and BusinessController. Both Controller constructors takes EntityManager as a parameter which is an abstract class. I would like to resolve Each Manager class depending on the controller I am using.
For PayerController I would like to inject PayerManager class and for BusinessController I would like to inject BusinessManager.
Currentlly I am getting the last Object that has been resolved with EntityManager i.e BusinessManager.
I remember in Ninject we can do conditional injection pretty easily.
This is how current I am resolving the dependency But wont work.
Startup.cs
services.AddScoped(typeof(EntityManager), typeof(PayerManager));
services.AddScoped(typeof(EntityManager), typeof(BusinessManager));
Controllers
public class PayerController
{
private PayerManager Manager{get;}
public PayerController(EntityManager entityManager)
{
Manager = entityManager as PayerManager;
}
}
Manager Classes
public class PayerManager : EntityManager
{
public void MyPayer()
{
}
}
public class BusinessManager : EntityManager
{
public void MyBusiness()
{
}
}
public abstract class EntityManager
{
public string IAMCommon()
{
return "";
}
}
Upvotes: 4
Views: 6355
Reputation: 3
@Maxspan, my suggestion:
Put all interfaces in Contracts folder and this folder inside your Models/Entities folder (Models/Entities folder - Contracts folder)
IEntityManager Interface
namespace WebApplication1.Entities.Contracts
{
public interface IEntityManager
{
//Method signature only
string IAMCommon();
}
}
IBusinessManager Interface
namespace WebApplication1.Entities.Contracts
{
public interface IBusinessManager : IEntityManager
{
//Method signature only
void MyBusiness();
}
}
IPayerManager Interface
namespace WebApplication1.Entities.Contracts
{
public interface IPayerManager : IEntityManager
{
//Method signature only
void MyPayer();
}
}
BusinessManager Concrete Class
using System;
using WebApplication1.Entities.Contracts;
namespace WebApplication1.Entities
{
public class BusinessManager : IBusinessManager
{
//Method signature in IEntityManager
public string IAMCommon() //Heritage in IBusinessManager (IBusinessManager : IEntityManager)
{
//Implement your code here.
throw new NotImplementedException();
}
//Method signature in IBusinessManager
public void MyBusiness()
{
//Implement your code here.
throw new NotImplementedException();
}
}
}
PayerManager Concrete Class
using System;
using WebApplication1.Entities.Contracts;
namespace WebApplication1.Entities
{
public class PayerManager : IPayerManager
{
//Method signature in IEntityManager
public string IAMCommon() //Heritage in IPayerManager (IPayerManager : IEntityManager)
{
//Implement your code here.
throw new NotImplementedException();
}
//Method signature in IPayerManager
public void MyPayer()
{
//Implement your code here.
throw new NotImplementedException();
}
}
}
Startup class
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using WebApplication1.Entities;
using WebApplication1.Entities.Contracts;
namespace WebApplication1
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IBusinessManager, BusinessManager>();
services.AddScoped<IPayerManager, PayerManager>();
}
}
}
BusinessController
using Microsoft.AspNetCore.Mvc;
using WebApplication1.Entities.Contracts;
namespace WebApplication1.Controllers
{
public class BusinessController : Controller
{
private readonly IBusinessManager _businessManager;
public BusinessController(IBusinessManager businessManager)
{
_businessManager = businessManager;
}
public IActionResult Index()
{
//Both methods in BusinessManager due to heritage (BusinessManager : IBusinessManager)
_businessManager.IAMCommon();
_businessManager.MyBusiness();
return View();
}
}
}
PayerController
using Microsoft.AspNetCore.Mvc;
using WebApplication1.Entities.Contracts;
namespace WebApplication1.Controllers
{
public class PayerController : Controller
{
private readonly IPayerManager _payerManager;
public PayerController(IPayerManager payerManager)
{
_payerManager = payerManager;
}
public IActionResult Index()
{
//Both methods in PayerManager due to heritage (PayerManager : IPayerManager)
_payerManager.IAMCommon();
_payerManager.MyPayer();
return View();
}
}
}
Upvotes: 0
Reputation: 1107
Make interface for each concrete class and Injecting interface in the controller
Startup.cs
services.AddScoped<IPayerManager, PayerManager>();
services.AddScoped<IBusinessManager, BusinessManager>();
Controllers
public class PayerController
{
private IPayerManager _entityManager{get;}
public PayerController(IPayerManager entityManager)
{
_entityManager= entityManager;
}
}
public class BusinessController
{
private IBusinessManager _entityManager{get;}
public BusinessController(IBusinessManager entityManager)
{
_entityManager= entityManager;
}
}
Manager Classes
public class PayerManager : EntityManager,IPayerManager
{
public void MyPayer()
{
}
}
public class BusinessManager : EntityManager,IBusinessManager
{
public void MyBusiness()
{
}
}
public abstract class EntityManager
{
public string IAMCommon()
{
return "";
}
}
Interfaces
public interface IPayerManager
{
void MyPayer();
}
public interface IBusinessManager
{
void MyBusiness();
}
Upvotes: 1
Reputation: 4553
I don't understand why you think you need conditional dependency injection in this situation because the solution to make it work is very simple.
You can change your controllers to inject the correct type of dependency that they need.
public class PayerController
{
private PayerManager Manager { get; }
public PayerController(PayerManager manager)
{
Manager = manager;
}
}
public class BusinessController
{
private BusinessManager Manager { get; }
public BusinessController(BusinessManager manager)
{
Manager = manager;
}
}
Then make sure both types are registered in the service container.
services.AddScoped<PayerManager>();
services.AddScoped<BusinessManager>();
UPDATE
A better way is to use interfaces and possibly an abstract generic controller.
Define your interfaces:
public interface IEntityManager { }
public interface IPayerManager : IEntityManager { }
public interface IBusinessManager : IEntityManager { }
Update your classes to implement the interfaces:
public abstract class EntityManager : IEntityManager
{
protected EntityManager() { }
}
public class PayerManager : EntityManager, IPayerManager
{
public PayerManager() : base() { }
}
public class BusinessManager : EntityManager, IBusinessManager
{
public BusinessManager() : base() { }
}
Then create a base controller class:
public abstract class EntityController<T> : Controller where T : class, IEntityManager
{
protected(T manager)
{
Manager = manager
}
protected T Manager { get; }
}
Change your controllers to inherit from base controller:
public class PayerController : EntityController<IPayerManager>
{
public PayerController(IPayerManager manager) : base(manager) { }
}
public class BusinessController : EntityController<IBusinessManager>
{
public BusinessController(IBusinessManager manager) : base(manager) { }
}
And update the service register:
services.AddScoped<IPayerManager, PayerManager>();
services.AddScoped<IBusinessManager, BusinessManager>();
Upvotes: 3