Dependency Resolver using Ninject - asp.net

I am always getting the error
No parameterless constructor defined for this object.
when I execute the codes below.
It must be something to do with my ninject modules.
What seems to be the problem here?
Controller
public class AccountController : Controller
{
private readonly IUserService _service;
public AccountController(IUserService service)
{
_service = service;
}
}
Service Layer
public class UserService : ServiceBase<User>, IUserService
{
public UserService(IRepository repository) : base(repository)
{
}
}
public interface IUserService : IService<User>
{
}
Repository
public class UserRepository : RepositoryBase<User>, IUserRepository
{
}
public interface IUserRepository : IRepository<User>
{
}
Ninject ----
ServiceModule
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IUserService>().To<UserService>();
}
}
RepositoryModule
public class RepositoryModule : NinjectModule
{
public override void Load()
{
Bind<IUserRepository>().To<UserRepository>();
}
}
Setup
public static void SetupDependencyInjection()
{
// Create Ninject DI kernel
var kernel = CreateKernel();
// Tell ASP.NET MVC 3 to use our Ninject DI Container
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
private static IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new ServiceModule(),
new RepositoryModule()
};
return new StandardKernel(modules);
}

Have have registered:
Bind<IUserRepository>().To<UserRepository>();
But you are referring to the base IRepository interface in UserService:
public UserService(IRepository repository) : base(repository)
{
}
So Ninject won't know how to construct a generic IRepository. You need to Bind a implementation for IRepository. Or use IUserRepository in UserService:
public UserService(IUserRepository repository) : base(repository)
{
}

Related

How to use public methods from other ASP.NET Core controller in solution?

I am programming a Web API using ASP.NET Core in connection with a web application. I am looking for a way to call a method (for example methodCallableFromOtherControllers) from another controller without it being callable from the client (vus.js). Thanks in advance for the support!
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[HttpPost]
[Route("get_test")]
public string get_test([FromBody] Test test)
{
}
public string methodCallableFromOtherControllers()
{
}
}
Pls allow me to add my ideas here to describe it clearly.
Let's assume that there're 2 controllers here: HomeController and HelloController
And this is my HelloController:
namespace WebApi_net5.Controllers
{
public class HelloController : ControllerBase
{
[HttpGet("getHello")]
public string Index()
{
return "hello";
}
}
}
If I wanna call this Index() method from HomeController, I provide these 2 ways:
public class HomeController : ControllerBase
{
[HttpGet("test")]
public string test() {
var controller = new HelloController();
string temp = controller.Index();
return "a"+ temp;
}
}
Or using AddControllersAsServices() in startup.cs
public class HomeController : ControllerBase
{
private HelloController _controller;
public HomeController(HelloController controller) {
_controller = controller;
}
[HttpGet("test")]
public string test() {
string temp = _controller.Index();
return "a"+ temp;
}
}
startup.cs ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
//services.AddControllers();
services.AddControllers().AddControllersAsServices();
}

Asp.NET MVC Autofac Inject Dependence non-controller class

All classes that inherit from controller have already inserted the dependencies, but I do not know how to inject those who do not inherit from contoller.
in the example below the SendEmailAndLog() method waits for the ILoggerService interface to be injected. but I do not know how to do this.
public async Task Execute(IJobExecutionContext context)
{
SendEmailHelper sendEmailHelper = new SendEmailHelper();
await sendEmailHelper.SendEmailAndLog(user, "Task", user.UserName, UserManager, loggerService);
}
this task is called the method Application_Start() on Global.asax.cs
I created a constructor to receive this service as a parameter, this is working for the methods within the controllers that call the Class Emailservice. However there are classes that do not inherit from controller so I do not know how to inject.
My Service is:
public interface ILoggerService
{
void Error(ExceptionLogger exception);
void SaveLog();
}
public class LoggerService : ILoggerService
{
private readonly ILoggerRepository loggerRepository;
private readonly IUnitOfWork unitOfWork;
public LoggerService(ILoggerRepository loggerRepository, IUnitOfWork unitOfWork)
{
this.loggerRepository = loggerRepository;
this.unitOfWork = unitOfWork;
}
public void Error(ExceptionLogger exception)
{
loggerRepository.Error(exception);
}
public void SaveLog()
{
unitOfWork.Commit();
}
}

RunWith SpringJUnit4ClassRunner gives error fail to load ApplicationContext with InitializingBean

I am using InitializingBean to initialise static properties in a modal class. This object I am auto wiring in a service
When I write a test case of service, I throws error: Failed to load ApplicationContext
Config class
public class AppConfig {
private String prop1;
protected void setProp1(String prop) {
this.prop1 = prop;
}
public String getProp1() {
return prop1;
}
}
PropertyIntilizer class
public class PropertyIntializer implements InitializingBean {
#Autowired
private AppConfig appConfig;
#Override
public void afterPropertiesSet() throws Exception {
appConfig.setProp1("PROP");
}
}
Service Class
#Service
public class Service {
#Autowired
private AppConfig appConfig;
public void doSomething(){
System.out.println(appConfig.getProp1());
}
}
TestClass
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { TestConfig.class })
public class ServiceTest {
#Autowired
private Service service;
#Test
public void testService(){
service.doSomething();
}
}
This gives an error : Failed to load ApplicationContext
But when I remove Autowired AppConfig, it works
Edit:
TestConfig class
#Configuration
#ComponentScan(basePackages = { "base.package" })
public class TestConfig {
}
my main classes are in base.package.main and test classes in base.package.test
similar issue got resolved for me by adding JRE(thats comes with application server in my case websphere) in buid path

Spring MVC - How to create a proper Service layer?

I'm using SpringBoot and I am trying to create a service layer for my web application but i cant make it work.
My classes look like this
ServiceFactory
#Service
public class ServiceFactory {
#Autowired
public static EncuestaService getEncuestaService()
{
return new EncuestaServiceImpl();
}
}
EncuestaService
public interface EncuestaService {
void crearEncuesta(Encuesta encuesta, Map<String,String> parametros);
}
EncuestaServiceImpl
#Service
public class EncuestaServiceImpl implements EncuestaService {
#Override
public void crearEncuesta(Encuesta encuesta, Map<String, String> parametros) {
CrearEncuesta nueva = new CrearEncuesta(encuesta,parametros);
nueva.execute();
}
}
CrearEncuesta
#Service
public class CrearEncuesta {
private Encuesta encuesta;
private Map<String,String> parametros;
#Autowired
private RespuestasRepository respuestasRepository;
#Autowired
private EncuestasRepository encuestasRepository;
public CrearEncuesta(Encuesta encuesta, Map<String,String> parametros) {
super();
this.encuesta = encuesta;
this.parametros = parametros;
}
public void execute()
{
encuestasRepository.save(encuesta);
}
}
Everytime I call ServiceFactory.getEncuestasService().crearEncuesta() from any Controller it returns me a NullPointerException.
From what I have been reading I should not be creating a new EncuestsaServiceImpl() in my ServiceFactory but I don't really know the correct way to do so. I would appreciate if anyone could help me out :P.
Edit:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
Controller
#Controller
public class EncuestaController {
#RequestMapping(value ="registrarEncuesta", method = RequestMethod.POST)
private String formularioEncuesta(#Valid #ModelAttribute("formEncuesta") EncuestaForm formEncuesta, BindingResult bindingResult,#RequestParam Map<String,String> allRequestParams)
{
if (bindingResult.hasErrors()) {
return "nuevaEncuesta";
}
try {
Encuesta nueva = formEncuesta.toEncuesta();
ServiceFactory.getEncuestaService().crearEncuesta(nueva,allRequestParams);
} catch (DataIntegrityViolationException e) {
return "nuevaEncuesta";
}
return "redirect:/encuestas";
}
}
You will have to read a little bit more about dependency injection. The central principle in Spring Framework is dependency injection which should be used to avoid referencing beans (service implementations, repository implementations etc...) statically. Spring container also servers as a bean factory that will instantiate and inject (autowire) implementations to beans that need them.
Because Spring will instantiate service interface implementations for you, you don't need ServiceFactory. In your controller you need to add a reference (a field) to EncuestaService and annotate it as Autowired and Spring will wire in the implementation. And then you can just use it in your controller.
#Controller
public class EncuestaController {
#Autowired
EncuestaService encuestaService;
#RequestMapping(value ="registrarEncuesta", method = RequestMethod.POST)
private String formularioEncuesta(#Valid #ModelAttribute("formEncuesta") EncuestaForm formEncuesta, BindingResult bindingResult,#RequestParam Map<String,String> allRequestParams)
{
if (bindingResult.hasErrors()) {
return "nuevaEncuesta";
}
try {
Encuesta nueva = formEncuesta.toEncuesta();
encuestaService.crearEncuesta(nueva,allRequestParams);
} catch (DataIntegrityViolationException e) {
return "nuevaEncuesta";
}
return "redirect:/encuestas";
}
}

ASP.Net MVC TDD using Moq

I am trying to learn TDD/BDD using NUnit and Moq.
The design that I have been following passes a DataService class to my controller to provide access to repositories.
I would like to Mock the DataService class to allow testing of the controllers.
There are lots of examples of mocking a repository passed to the controller but I can't work out how to mock a DataService class in this
scenerio.
Could someone please explain how to implement this?
Here's a sample of the relevant code:
[Test]
public void Can_View_A_Single_Page_Of_Lists()
{
var dataService = new Mock<DataService>();
var controller = new ListsController(dataService);
...
}
namespace Services
{
public class DataService
{
private readonly IKeyedRepository<int, FavList> FavListRepository;
private readonly IUnitOfWork unitOfWork;
public FavListService FavLists { get; private set; }
public DataService(IKeyedRepository<int, FavList> FavListRepository,
IUnitOfWork unitOfWork)
{
this.FavListRepository = FavListRepository;
this.unitOfWork = unitOfWork;
FavLists = new FavListService(FavListRepository);
}
public void Commit()
{
unitOfWork.Commit();
}
}
}
namespace MyListsWebsite.Controllers
{
public class ListsController : Controller
{
private readonly DataService dataService;
public ListsController(DataService dataService)
{
this.dataService = dataService;
}
public ActionResult Index()
{
var myLists = dataService.FavLists.All().ToList();
return View(myLists);
}
}
}
Create an interface like this:
public interface DataService
{
FavListService FavLists { get; }
void Commit();
}
Make your DataService implement this interface and your controller should depend on this interface. Problem solved :)
EDIT: This line of code:
dataService.FavLists.All().ToList();
is breaking the law of demeter and will be a pain to unit test your service. Create a method like AllFavList() on your service instead of all these chain of calls, it will be easier to mock.
EDIT2: How to mock you get property
dataService.SetupGet(d => d.FavLists).Returns(your_variable);

Resources