Play and Guice Dependency Injection with Interface - dependency-injection

I'm trying to use Play/Guice dependency injection with an interface:
public interface IService {
Result handleRequest();
}
public Service implements IService {
#Override
public Result handleRequest() {
...
return result;
}
}
public class Controller {
private final IService service;
#Inject
public Controller(IService service) {
this.service = service;
}
}
I get:
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1.) No implementation for IService was bound.
If I change the controller class to not use the interface it works fine:
public class Controller {
private final Service service;
#Inject
public Controller(Service service) {
this.service = service;
}
}
How do I make it work with the interface so it finds the concrete Service class?

You can use guice annotation #ImplementedBy like this:
import com.google.inject.ImplementedBy;
#ImplementedBy(Service.class)
public interface IService {
Result handleRequest();
}
Or u can use modules like this:
import com.google.inject.AbstractModule;
public class ServiceModule extends AbstractModule {
protected void configure() {
bind(IService.class).to(Service.class);
}
}
And then register them in application.conf play.modules.enabled += "modules.ServiceModule"

Related

hk2: why bind(X.class).to(X.class)

I am learning Java, but found the following piece of code. I am confused. What is bind(X.class).to(X.class); for?
import org.glassfish.hk2.utilities.binding.AbstractBinder;
public class ApplicationBinder extends AbstractBinder {
#Override
protected void configure() {
bind(X.class).to(X.class);
}
}
Thanks
You're configuring how you want your services to be discovered in the DI (dependency injection) system. bind(Service).to(Contract) is basically saying that you want to provide the Service as an injectable service, and want to "advertise" it as Contract. By "advertise", I mean what you want to be able to inject it as. For instance Service can be UserRepositoryImpl, while Contract can be UserRepository (interface). With this you would only be able #Inject UserRepository as that's what you advertise. The benefit of this is all the benefits that come with programming to an interface.
Example
interface UserRepository {
List<User> findAll();
}
class UserRepositoryImpl implements UserRepository {
#Override
public List<User> findAll() {
return Arrays.asList(new User("username"));
}
}
#Path("users")
class UserResource {
#Inject
private UserRepository repository;
#GET
public List<User> getUsers() {
return repository.findAll();
}
}
class JerseyApp extends ResourceConfig {
public JerseyApp() {
register(UserResource.class);
register(new AbstractBinder() {
#Override
public void configure() {
bind(UserRepositoryImpl.class)
.to(UserRepository.class);
}
});
}
}
Here the UserRepository is injected into the UserResource. When the DI system injects it, it will actually be the UserRepositoryImpl instance.
By doing that you are actually binding a new contract to a service.
bind(Service.class).to(Contract.class);
OR (binding a new contract to a service in Singleton)
bind(Service.class).to(Contract.class)..in(Singleton.class);

AutoFac DI in static class

We have a ASP.NET project, and we use AutoFac to DI.
We have a Service layer with all database queries and we need to make some queries in a static class.
This is how we register the dependencies in the Global.asax:
public class Dependencies
{
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
builder.RegisterModule(new ServiceModule());
builder.RegisterModule(new EfModule());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
public class ServiceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(Assembly.Load("MyApp.Service")).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
}
}
public class EfModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType(typeof(myDataContext)).As(typeof(IMyContext)).InstancePerLifetimeScope();
}
}
And this is how we access in the controller:
public class SomeController : Controller
{
private readonly IService1 _service1;
private readonly IService2 _service2;
public SomeController(IService1 service1, IService2 service2)
{
_service1 = service1;
_service2 = service2;
}
public ActionResult Index()
{
var service = _service1.GetAll();
...
return View(searchModel);
}
}
Now we need to retrieve data from the database in a static class, so we have to call our service layer, but we don't know how to do it...we have seen this, but I don't know if it is correct, but it works.
public static Test ()
{
...
var service1 = DependencyResolver.Current.GetService<IService1>();
...
}
Also, how it would be in both, non-static and static classes?
Thanks in advance.
The problem is I have to call many of those classes from different places and I don't want to depend on having the service in order to call the class, I'd like the class to take care of everything.
In this case you should register your class with Autofac so that it gets its dependencies injected:
builder.RegisterType<MyClass>();
If the class is used several times during a single request it might be useful to register it using InstancePerLifetimeScope(), but that depends on your overall architecture. See this link to the Autofac documentation for more information.
Of course you have to change your class so that the methods are not static any more and add an constructor to get the dependencies:
public class MyClass
{
private readonly IService1 _service1;
public MyClass(IService1 service1)
{
_service1 = service1;
}
public void Test
{
// use the _service1 instance to do whatever you want
}
}
Now you can inject the MyClass dependency in your controller and use it without having to know anything about its internals or its dependencies:
public class SomeController : Controller
{
private readonly IService1 _service1;
private readonly IService2 _service2;
private readonly MyClass _myClass;
public SomeController(IService1 service1, IService2 service2, MyClass myClass)
{
_service1 = service1;
_service2 = service2;
_myClass = myClass;
}
public ActionResult Index()
{
var service = _service1.GetAll();
...
_myClass.Test();
return View(searchModel);
}
}

how to implement dependency injection in mvc?

I'm trying to implement dependency injection but i know how to implement the interface and repository of classes then i don't know what shall i do.
This my sample:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}
This is my interface:
public interface IUser
{
IEnumerable<User> GetUsers();
void AddUser(User user);
void EditUser(User user);
void DeleteUser(int id);
User UserGetById(int id);
void Save();
}
This is my repository:
public class UserRepsitory:IUser
{
private _Context _context;
public UserRepsitory(_Context _context)
{
this._context = _context;
}
public IEnumerable<User> GetUsers()
{
return _context.User.ToList();
}
public void AddUser(User user)
{
_context.User.Add(user);
}
public void EditUser(User user)
{
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
}
public User UserGetById(int id)
{
return _context.User.Find(id);
}
public void Save()
{
_context.SaveChanges();
}
public void DeleteUser(int id)
{
var Search = _context.User.Find(id);
_context.User.Remove(Search);
}
}
And one of method in controller:
private IUser userRepsitory;
public UsersController()
{
this.userRepsitory = new UserRepsitory(new _Context());
}
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
What is the next step?
The first thing is, get rid of the default constructor where we are hard coding the initialization of UserRepository ! We will do that in the dependency injection way.
public UsersController : Controller
{
private readonly IUser userRepsitory;
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
}
Now we need something to tell the MVC framework which version/implementation of IUser should be used when the code runs. you can use any dependency injection frameworks to do that. For example, If you are in MVC 6, you can use the inbuilt dependency injection framework to do that. So go to your Startup class and in your ConfigureServices method, you can map an interface to a concrete implementation.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IUser, UserRepository>();
}
}
If you are in a previous version of MVC, you may consider using any of the dependency injection frameworks available like Unity, Ninject etc.
It is pretty much same, you map an interface to a concrete implementation
Ninject
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUser>().To<UserRepository>();
}
You do not need to put the mapping in a cs file. You can define that in a config file. For example, when you use Unity you can do something like this in your config file (web config or an external config file for unity configuration)
Unity
<alias alias="IUser" type="YourNamespace.IUser, YourAssemblyName" />
<register type="IUser" mapTo="YourNamespace.UseRepository, YourAssemblyName">
In order to create and configure your project with Spring DI(Dependency Feature) you must configure beans.
Create an xml file (if its not there) and add references to bean
In this xml file, provide references to the classes you want to inject. Example:
<bean id="Name of the JAVA Class" class="the Full path of the JAVA class"/>
And in your class where you are supposed to call the referencing class(above), calling procedure would be like :
#Controller
public class MyController {
private full.path.of.my.class.named.MyJavaClass _class;
#Autowired
private MyController (full.path.of.my.class.MyJavaClass class)
{
this._class= class;
}
}
Now say if you a function in MyJavaClass
public int sum(int x, int y){
return x+y;
}
Then without creating object of MyJavaClass you can inject like the following in your controller:
_class.Sum(10,15);
YOU DO NOT CREATE AN INSTANCE OF THIS CLASS.

Quartz .net does not work when I inject dependency

I am using Quartz .net v2.3.3.0 and Castle Windsor v3.3.0.0.
I have a job which is dependent on a Service
public class DemoJob : IJob
{
private readonly IService _Service;
public DemoJob(IService Service)
{
_Service = Service;
}
public void Execute(IJobExecutionContext context)
{
_Service.CallRepoMethod();
}
}
This is the service class which is in different project
public class Service: IService
{
public void CallRepoMethod()
{
Repo();
}
}
Everything works fine till now.
But as soon as I inject dependency in service class the job is not executed.
public class Service: IService
{
private readonly IRepository _repository;
Service(IRepository repository)
{
_repository = repository;
}
public void CallRepoMethod()
{
_repository.Repo();
}
}
IRepository is implemented by a simple Repository class with a single method.
Repository class is in different project and IService,Service and IRepository are in same project.
I don't get any error message but the job does not get executed. If i remove dependency from the Service class then everything works fine and jobs execute.
Here is how I have registered the dependencies
internal class CastleWindsorContainer : IContainer
{
public static WindsorContainer Container { get; private set; }
public CastleWindsorContainer()
{
Container = new WindsorContainer();
}
public void Register()
{
Container.Register(Component.For<IRepository>().ImplementedBy<Repository>().LifestyleTransient());
public Object Resolve(Type controllerType)
{
return Container.Resolve(controllerType);
}
public void Release(IController controller)
{
Container.Release(controller);
}
public void RegisterJobs(IJobFactory jobFactory)
{
Container.Register(Component.For<IJobFactory>().Instance(jobFactory).LifestyleTransient());
Container.Register(Component.For<IQuartzInitializer>().ImplementedBy<JobsConfig>().LifestyleTransient());
Container.Register(Component.For<IService>().ImplementedBy<Service>().LifestyleTransient());
Container.Register(Component.For<DemoJob>().ImplementedBy<DemoJob>().LifestyleTransient()
);
Container.Resolve<IQuartzInitializer>().RegisterJobs();
}
}
code in Global.asax
var container = new CastleWindsorContainer();
IJobFactory jobFactory = new WindsorJobFactory(container);
container.Register();
container.RegisterJobs(jobFactory);
I am not able to figure out what's wrong. I searched for the solution and found many links but it didn't help because all of them show only one level of dependency. What if the dependent class is dependent on another class?
You can find my demo project here:DemoProject
Some links I checked
Quartz .net Windsor Facility
Thank You

What is the correct way to register FluentValidation with Simple Injector?

I am able to register FluentValidation AbstractValidators using a FluentValidatorFactory. However, it doesn't feel right, because not all of the IoC container registrations happen during bootstrap / composition root. Instead, the fluent validators are registered by a separate factory:
The composition root:
public class SimpleDependencyInjector : IServiceProvider
{
public readonly Container Container;
public SimpleDependencyInjector()
{
Container = Bootstrap();
}
internal Container Bootstrap()
{
var container = new Container();
container.Register< // ...register all non-fluent-validator types, then
container.Verify();
return container;
}
public object GetService(Type serviceType)
{
return ((IServiceProvider)Container).GetService(serviceType);
}
}
An abstract fluent validator factory depending only on IServiceProvider
public abstract class FluentValidatorFactory : ValidatorFactoryBase
{
private IServiceProvider Injector { get; set; }
protected FluentValidatorFactory(IServiceProvider injector)
{
Injector = injector;
}
public override IValidator CreateInstance(Type validatorType)
{
return Injector.GetService(validatorType) as IValidator;
}
}
A fluent validator factory implementation for SimpleInjector
public class SimpleValidatorFactory : FluentValidatorFactory
{
public SimpleValidatorFactory(SimpleDependencyInjector injector)
: base(injector)
{
var validators = AssemblyScanner.FindValidatorsInAssembly(
Assembly.GetCallingAssembly());
validators.ForEach(validator =>
injector.Container.Register(
validator.InterfaceType, validator.ValidatorType));
injector.Container.Verify();
}
}
SimpleInjector has good support for open generics, and all of my fluent validator classes have signatures similar to the following:
public class SomeClassValidator : AbstractValidator<SomeClass>
{
public SomeClassValidator([depedencies injected here])
{
// ... set up validation rules
}
}
So, is there a better way to register the validators in the bootstrap / composition root, instead of using fluent's validator factory?
P.S. #DotNetJunkie -- would be great if you had a wiki page on this at simpleinjector.codeplex.com.
I think I figured this out myself.
1.) Register fluent's open generic IValidator<T> interface in the composition root:
public class SimpleDependencyInjector : IServiceProvider
{
public readonly Container Container;
public SimpleDependencyInjector()
{
Container = Bootstrap();
}
internal Container Bootstrap()
{
var container = new Container();
// some container registrations
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
container.RegisterManyForOpenGeneric(typeof(IValidator<>), assemblies);
// some more registrations
container.Verify();
return container;
}
public object GetService(Type serviceType)
{
return ((IServiceProvider)Container).GetService(serviceType);
}
}
2.) Get rid of the SimpleValidatorFactory class.
3.) Make the FluentValidatorFactory a non-abstract, concrete class:
public class FluentValidatorFactory : ValidatorFactoryBase
{
private IServiceProvider Injector { get; set; }
public FluentValidatorFactory(IServiceProvider injector)
{
Injector = injector;
}
public override IValidator CreateInstance(Type validatorType)
{
return Injector.GetService(validatorType) as IValidator;
}
}
4.) Register the FluentValidatorFactory as the validation factory provider in global.asax:
var injector = new SimpleDependencyInjector();
FluentValidationModelValidatorProvider.Configure(
provider =>
{
provider.ValidatorFactory = new FluentValidatorFactory(injector);
}
);

Resources