Can I use method of service layer class in non mvc class? - spring-mvc

I want to know whether I can use object of service layer marked with #Service annotation and call one of its method in non mvc-spring class ?
Say there is a method getUsers() in service layer which calls getUsers() of Dao layer. In order to use it in contoller I have to add the #Autowired-annotation in the service layer instance. But if I want to use the class method getUsers() in non-mvc class, how can I do that?

In order to use a service, that object must be container managed. That is, this object's life cycle must be managed by Spring (creation, destruction, initialisation,...).
So to inject an instance of your service in an object, it must be a Spring bean too (Service, Component, Controller...).
So, it may be an MVC object, but it doesn't have to.
On the other hand, there is another alternative: use the annotation #Configurable.
An object with this annotation can be application managed but Spring, using byte code aspects, can inject it's dependencies. So although you create the object with a new statement, Spring instruments this call and resolve all the annotated dependencies.
Read this for more detail:
http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/html/ch08s08.html

Related

Multi-Tenant ASP.NET Core

How would you configure the middleware to change the DBContext connection string based on a sub-domain of the income request?
It appears that the DBContext is set in the Startup... which looks too early to determine the HTTPRequest to resolve the connection string.
Well, this might not suit your needs entirely, but here's what I would do:
Create a DbContextFactory class. This DbContextFactory class can create instances of the DbContext and can pass in any string to the DbContext constructor. Then inject this factory and whenever you need an instance of the dbcontext, just ask the factory to return one for you. Of course you have to manage the lifetime of the created contexts yourself (i.e. using block).
Another option can be to create the DbContextFactory so that it holds an instance of a DbContext. When you ask for a context object from the factory, the factory creates a new one and also stores it in a private field, and subsequent calls return that same instance. Make the factory IDisposable and in its Dispose() method, dispose the context as well. This way you don't have to worry about managing lifetime (if you use a Scoped registration).

Understanding IOC Container Injection

I am new to spring and not able to understand when to instantiate the class with new operator and when by using spring container.
example i found a code
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
EmployeeDao dao=(EmployeeDao)ctx.getBean("edao");
int status=dao.saveEmployee(new Employee(102,"Amit",35000));
System.out.println(status);
int status=dao.updateEmployee(new Employee(102,"Sonoo",15000));
System.out.println(status);
Employee e=new Employee();
e.setId(102);
int status=dao.deleteEmployee(e);
System.out.println(status);
}
}
i am using jdbc template. i have a doubt why we have new to instatiate employee class instead we should have used (Employee)ctx.getBean("employee"). using new operator would create dependency?
Pls help
From ProSpring book,
"Of the applications that we have built using Spring,
the only objects that are consistently not managed by Spring are domain objects. (Even though in Spring
it’s possible to have Spring manage domain objects by applying the #Component annotation to the classes
and assigning them with prototype scope, most of the time we will choose to manage domain objects
within the application.) The reason for this is that, practically, Spring does not need to be involved with
domain objects. Generally, you create many instances of your domain objects using the new() operator
and perform processing either in the service or data access layer. Although Spring also supports the
injection of new instance of domain objects every time it was requested (by using the bean scope
prototype), generally developers will not adopt this approach since typically domain objects do not take
advantage of Dependency Injection, because they generally have few dependencies outside of the DOM
itself, and they don’t require much configuration."
So, yes you could create beans of type Employee but then they wil have to be defined as prototype as be default all beans in spring are singletons. because there can be many employees and their objects, you obviously cannot have Employee as a singleton. but your concentration as to the utilization of spring features should be much more than managing domain objects.
The Spring IOC container is at the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete lifecycle from creation till destruction.The IoC container gets informations/metadata either from XML or by Java annotations, or by Java code.
Yeah you can create Employee bean in your spring context xml file and make sure scope is prototype as
<bean id="employee" class="com.mycompany.Employee" scope="prototype"/>
so that on every request of Employee bean, you will get a new object Employee.
There are other scopes of beans
singleton : This scopes the bean definition to a single instance per Spring IoC container (default).
request : On every HTTP request a new bean will created and delivered.
prototype : on every request(api request) a new bean will be created.
session : This scope a bean definition to an HTTP session.
Note : It is not recomemded to create beans for database model class.because your persistent layer will take care of it.

How to call a non static method of controller in spring only once whenever my application gets started

I am new to Spring MVC and being stuck with a problem.
I have to call a method only once after my application gets started. is there is any annotation for that. I don't want to use init config and #PostConstruct because for that I need to create an object of the bean. My method should get called only once as soon as my application gets started.
I am using Spring MVC 3
Thanks
If it's a non-static method, then you need an instance to invoke the method on. If the instance depends on beans in the context, then the appropriate way is to define a bean for it and use #PostConstruct. If the instance doesn't have any dependencies on the ApplicationContext, just create it yourself and call its method.
I guess your context is loading in the start up. You can use this to do that
<bean name="YOUR_BEAN_NAME" init-method="YOUR_METHOD_NAME" class="YOUR_CLASS_NAME" lazy="false" />

ASP.NET MVC - Using UnitOfWork

I'm currently working on a web app which consist of 6 layers:
Web (reference to ViewModels and Controllers)
ViewModels
Controllers
Services (reference to Data and Entities)
Data (reference to Entities)
Entities
What I'm trying to is to implement a "UnitOfWork" pattern, and therefore I have a class thats injected by DI for that job which makes it possible to do .commit() in the actionresult in the controller when I'm done with the database.
Now is my question... Where should this UnitOfWork class be placed? It's at the moment in my Data layer but that requires the Controller layer to reference the Data layer AND the Service layer, which is odd in my opinion... Should I move the UnitOfWork class/interface to the Service layer and use DI?
Unless you're using the Repository pattern in your Data layer, you're wasting your time.
The point of a UoW is to handle changes across multiple Repository instances, this is done in the following ways:
Unit of Work derives from the actual underlying context (DataContext - L2SQL, ObjectContext/EF)
Repositories take a Unit of Work in their ctor.
The Unit of Work do two things:
Have a Commit() method
Expose the underlying object/entity set to the Repository.
It's a little tricky to get it all setup, but once you do, the flow should be like this:
Controller get's DI'ed a service and a unit of work (both via Interfaces)
Controller calls method on a service ("CustomerServices.AddOrder()")
Service calls method on Repository
Repository calls "Add" method on "Order" object/entity set
Controller commits Unit of Work
Essentially, each layer takes an instance of the "next layer" in their constructor. Everything should be DI'ed and interface-driven. The UoW has not reliance on anything - but the Repository relies on it for persistence to the "internal memory" (ORM), then the UoW "Commit" will push the changes out to the database (basically wraps the "SaveChanges" method).
As the Unit of Work is an infrastructure/persistence/database/transactional concern, it should go into your Data layer. Should only be referenced by Controllers.
I implemented my IUnitOfWork class to be passed directly into my MVC controllers (injected via Castle Windsor). I then have my controller pass it to any service objects it instantiates.
IUnitOfWork should be an interface for data layer. When request come into Controller then call service methods, if you require CRUD there should call UnitOfWork. You may use Session Per Request by call UnitOfWork in Global.asax Request_Start and commit works in Request_End.

Using Structuremap how do i inject a property of an MVC Controller into the Constructor of a Service the Controller uses

I'm new to using StructureMap as an IOC container for asp.MVC. One of my controllers takes an IStreamService interface in the constructor.
This is easily linked to a concrete class implementation of StreamService like so
For<IStreamService>().HttpContextScoped().Use<StreamService>();
The problem i'm facing is that the concrete class constuctor takes an IPrincipal parameter, which needs to be injected. I want to pass the User property of the instantiating Controller into the Concrete Service. Could someone please point me in the right direction?
No problem, just add this line to your configuration:
For<IPrincipal>().Use(() => HttpContext.Current.User);
The use of a lambda causes this to be evaluated every time the dependency is requested (as opposed to being a single instance at configuration time.

Resources