I've hooked up Ninject (correctly) to bind NLog. Here is my RegisterService method in my NinjectMVC3.cs
kernel.Bind<ILogger>().To<NLogger>();
I'm trying to port over to PetaPoco and have created a base controller here:
public class BaseController : Controller
{
protected PetaPoco.Database _database;
protected ILogger _logger;
protected MemberRepository _members;
public BaseController(ILogger logger)
{
_database = new PetaPoco.Database("TalentSiteConnection");
_members = new MemberRepository(_database);
_logger = logger;
}
}
When I inherit my base controller like so:
public class TestController : BaseController
{
public ActionResult Index()
{
TestViewModel model = new TestViewModel();
model.Member = _members.Single<Member>(2579);
return View("Index", model);
}
}
and try to run a build I'm getting a
'BaseController' does not contain a constructor that takes 0 arguments
What am I doing wrong? I thought Ninject would resolve the dependency on the constructor?
.
TestController needs that ctor...
public class TestController : BaseController
{
public TestController(ILogger logger) : base(logger) {}
...this has nothing to do with NInject. If you added a parameterless ctor to BaseController and left your TestController as is, you wouldn't get the logger injection.
Related
I'm using SpringBoot 2.2.6 and I want to know if is it possibile to Inject a DTO inside my Controller. It is a DTO with info coming from various entities..
For example I have a service that build this DTO:
#Service
public class SomeService() {
public ThisDTO getThisDTO() {
Entity entity = repository.findBySome();
return transformToDto(entity);
}
}
Now suppose I have a Controller like this:
#RestController
#RequestMapping(value = "/api/v1/Test")
public void TestController {
}
I would like to use ThisDTO in all method of above Controller but I don't want to do something like:
#RestController
#RequestMapping(value = "/api/v1/Test")
public void TestController {
#Autowired
SomeService someService;
#GetMapping
public void method1() {
ThisDTO thisDTO = someService.getThisDTO();
}
#GetMapping
public void method2() {
ThisDTO thisDTO = someService.getThisDTO();
}
...
...
}
but I would like to know if there's a way to do something like:
#RestController
#RequestMapping(value = "/api/v1/Test")
public void TestController {
#Inject // or something else
ThisDTO thisDto;
...
...
}
Thank you all!
I have this project structure
com.demo.application
- DemoApplication.java
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.out.println("inside main");
SpringApplication.run(DemoApplication.class, args);
}
}
I have another package
com.demo.application.employee
- EmployeeController.java
- EmployeeInterface.java
- Employee.java (Entity Bean)
#Controller
#RequestMapping("/getAll")
public class EmployeeController {
#Autowired
EmployeeInterface empInterface;
public ModelAndView getEmployees() {
System.out.println("inside controller");
return new ModelAndView("employee", "employee", empInterface.findAll());
}
}
#Repository
public interface EmployeeInterface extends JpaRepository<Employee, Long>{
}
When i access the below URL i get 404. The reason is the Controller and Repository beans are not loaded.
http://localhost:8080/getAll
Any help?
Your getAll does not associated with any controller handler.
Add #RequestMapping to your getEmployees() method:
#RequestMapping
public ModelAndView getEmployees() {
But it's not very intuitive. You should annotated your controller with the base path and your method with specific path:
#Controller
#RequestMapping("/employee")
public class EmployeeController {
#Autowired
EmployeeInterface empInterface;
#RequestMapping("/getAll")
public ModelAndView getEmployees() {
System.out.println("inside controller");
return new ModelAndView("employee", "employee", empInterface.findAll());
}
}
Now your URL looks like: localhost:8080/employee/getAll
In my Controller I have this
private readonly DbContext _context;
public CountryController(DbContext context)
{
_context = context;
}
How can I retrieve DbContext in other classes like static classes without passing as parameter to the method call
You can create new instances of your DBContext by creating services.
First you have to define an interface
public interface IMyService
{
void Test1();
}
then, you need to create the service class implementing the interface. Note that you request IServiceProvider to the Dependency Injector.
internal sealed class MyService : IMyService
{
private readonly IServiceProvider m_ServiceProvider;
// note here you ask to the injector for IServiceProvider
public MyService(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
m_ServiceProvider = serviceProvider;
}
public void Test1()
{
using (var serviceScope = m_ServiceProvider.CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<DbContext>())
{
// you can access your DBContext instance
}
}
}
}
finally, you instruct the runtime to create your new service a singleton. This is done in your ConfigureServices method in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// other initialization code omitted
services.AddMvc();
services.AddSingleton<IMyService, MyService>();
// other initialization code omitted
}
Note that MyService needs to be thread safe.
I try to use generic parameter in autowire but it doesn't work. My goal is to create a generic JSON controller with Spring 4.1.3 and Hibernate
I have a generic abstract class , and I use it to create service via a model objec(the same as my DAO) as generic parameter.
The code of my AbstractService
public interface IGenericService<T extends Serializable> extends IOperations <T>{}
public interface IOperations<T extends Serializable> {
T findOne(final long id);
List<T> findAll();
void create(final T entity);
T update(final T entity);
void delete(final T entity);
void deleteById(final long entityId);
List<T> findByField(String field, String value);
T save(final T entity);
}
//MyAbstractService (generic service)
public abstract class AbstractService<T extends Serializable> implements
IGenericService<T> {
public static final Logger logger = LoggerFactory
.getLogger(AbstractService.class);
public AbstractService(){}
...
#Override
#Transactional
public T update( T entity) {
logger.debug("public T update( T entity)");
return getDao().update(entity);
}
...
}
Now I create a SecuredUserService with this abstract service
#Transactional
#Component //(value = "userService")
#Qualifier("userService")
public class UserService extends AbstractService<SecuredUser> implements
IUserService {
// I override the method upate of the abstract service
#Override
#Transactional
public SecuredUser update(SecuredUser user){
... // password encoding for example
}
}
public interface IUserService extends IGenericService<SecuredUser> {
T findOne(final long id);
...
}
In my JUnit test I made autowire with this code :
#Autowire
IGenericService<SecuredUser> userGenericService;
Or
#Autowire
IUserService userService;
At this point every thing is ok, I use the overrided method of userService and not those of abstractService. I pass my Junit Test. An I create a package.
Now I want to make generic spring mvc controller to handle common Json request GET/PUT/DELETE/POST :
//Generic Controller
public abstract class GenericSecuredController <MODEL extends Serializable> extends CommonSecuredController {
/**
* spring generic service retrieve by MODEL class type
*/
#Autowired
private IGenericService <MODEL> genericService;
/**
* Spring generic URI retrieve by MODEL class type
*/
#Autowired
private IGenericURI<MODEL> genericURI ;
...
}
// interface to manage URI in a generic way
public interface IGenericURI<MODEL extends Serializable> {
// root for the controller
public static String CONTROLLER_MAPPING="" ;
// path to the file system
public static String PATH_MAPPING = "";
// key to retrieve data in path
public static String PATH="{id}";
// Json REST SERVICE MappedUri
public static String JSON_DUMMY = "/dummy";
public static String JSON_GET = "/" + PATH;
public static String JSON_GET_ALL = "";
public static String JSON_CREATE = "";
public static String JSON_DELETE = "/" + PATH;
public static String JSON_UPDATE = "/" + PATH;
public static String HTML_VIEW = "/{view}.view.html";
public String getControllerMapping() ;
public String getPathMapping() ;
}
// The specific URI for the SecuredUser model object
#Component
public class SecuredUserURI implements Serializable, IGenericURI<SecuredUser> {
public static final String CONTROLLER_MAPPING = "/user";
public static final String PATH_MAPPING = "user";
public String getControllerMapping() {
return CONTROLLER_MAPPING;
}
public String getPathMapping() {
return PATH_MAPPING;
}
}
Now I could create a specific controller for SecuredUser like this :
public class UserController extends GenericSecuredController<SecuredUser> {
/**
* creator to set Class type for the GenericSecuredController<MODEL>
*/
public UserController() {
super(SecuredUser.class);
}
}
The problem appear at this point. The autowire of the
IGenericURI<MODEL>
work fine, but the autowiring with
IGenericService <MODEL> genericService;
doesn't use the overrided specific method of the userService but the abstract method with common behaviour!!!
So my question is :
Is it possible to autowire bean with generic parameter like in my example.
Maybe there is to many level for Spring autowiring .
Other information :
As workaround, I try to pass the userService as parameter of the contoller but, the same behaviour: the generic service use the abstract method.
UPDATE : If I autowire IGenericService genericService in the UserController and create a new handler, the specific service is call.
Thanks
I am using AsyncTask and want to use getApplication() to work with class Application.
But gets error on getApplication() cannot find symbol.
my code:
public class splash extends AsyncTask {
protected config app;
public splash(Context context) {
super();
app = ((config) getApplication());
this.context=context;
}
and the class that I want to use:
public class config extends Application
{
public Boolean con=true;
public int status=-1;
public String actNum;
public void onCreate()
{
super.onCreate();
}
}
If you want to get the Application instance, you can initialize a member in onCreate() with it and have it returned by a class method:
public class ApplicationConfig extends Application {
private static ApplicationConfig instance;
public void onCreate() {
super.onCreate();
instance = this;
}
public static ApplicationConfig getConfig() {
return instance;
}
}
Then you can retrieve this instance everywhere via:
ApplicationConfig conf = ApplicationConfig.getConfig();