Structuring Dependency Injection for a Class with Injected Services AND Data - dependency-injection

I am using an IoC container that uses constructor injection (Castle Windsor, for example). I have the following (example) class which manages a product...
public class ProductDataManager
{
public ProductDataManager(Product product, IProductDataLoader productDataLoader)
{
}
// a number of methods here that manage the products data in different ways...
}
It has a dependency on a Product which is only known by the classes consumer. It also has a dependency on a product data loader service. I define the implementer of this service in the IoC container.
How do I define this class (ProductDataManager) in the IoC container (and/or the consuming class) so that the service dependency (IProductDataLoader) can be injected by the IoC container and the data dependency (Product) can be passed by the consuming class?
Or is this a code smell? If so, how can this be modified?

You can use the TypedFactoryFacility and do something like this (off the top of my head)... first, define an interface for your abstract factory:
public interface IProductDataManagerFactory
{
ProductDataManager Create(Product product);
}
Register the factory like so:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IProductDataManagerFactory>().AsFactory());
Now services can depend on IProductDataManagerFactory and have Windsor invoke container.Resolve through an automagically implemented factory.
Note that the parameter name product in the method signature must correspond to the parameter name in the ctor of ProductDataManager.

Related

Inject repository in service without DI framework

I have a requirement to create a simple REST API with basic CRUD operations on a resource, without using Spring but just Java.I use JAX-RS (Jersey implementation) and Jetty as an embedded servlet container.I use JPA (Hibernate implementation) and an H2 in-memory database. I don't use any DI framework so I do all the DI "manually" with new().
Below is a JAX-RS service that has a POST endpoint. I have created the repository as a static final variable inside the service. BookRepository is an interface and BookRepositoryImpl is the implementation of this repository. I wonder if this is the best approach. If I did this with Spring Autowired annotation, I would have a singleton repository so the only way I thought to emulate this is with a static final variable.
When the container runs, does a separate instance of the BookService gets created for each request (thread)?
So multiple threads will have access to a single copy of the bookRepository?
Isn't that what happens with the Autowired and singleton scope?
#Path("/books")
public class BookService {
private static final BookRepository bookRepository = new BookRepositoryImpl();
#POST
#Path("")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Book registerBook(Book b) {
return bookRepository.saveBook(b);
}
}
Applying Dependency Injection without a DI Container is a practice commonly referred to as Pure DI. With that approach you apply the same principles, practices, and patterns of object-oriented design and DI. But instead of wiring everything up using a DI Container, at the startup path of the application, you build your object graphs manually, using the new keyword.
Pure DI is a common—and valid—approach of practicing DI—DI Containers are useful, but optional tools.
This, however, is not the approach you are currently practicing. You are not injecting your dependencies into their consumers. By creating BookRepositoryImpl inside the BookService class, you are applying the Control Freak anti-pattern, with is a special form of a Dependency Inversion Principle violation. This tightly couples the BookRepositoryImpl class to the BookService class, which will likely cause maintainability issues, because BookRepositoryImpl is a Volatile Dependency. Volatile Dependencies are the reason we introduce abstractions and use Dependency Injection.
Besides, the use of static fields only magnifies the pain, because this might cause thread-safety issues in case BookRepositoryImpl (or one of its dependencies) isn't thread-safe.
So, instead of tightly coupling BookRepositoryImpl to BookService, you should inject the BookRepository abstraction into the BookService's constructor. This keeps the two components loosely coupled, and gives you all the benefits that loose coupling brings:
#Path("/books")
public class BookService {
private final BookRepository bookRepository;
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
#POST
#Path("")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Book registerBook(Book b) {
return bookRepository.saveBook(b);
}
}
This does mean, however, that you should override the way your REST API web framework creates that service. Such framework is typically only able to create instances on your behalf if they have a default constructor. I must admit that I have no experience with JAX-RS, but most frameworks allow overriding the creation of their root classes. With the Microsoft ASP.NET MVC framework, for instance, you can implement a custom IControllerFactory, and replace the framework's default implementation. Inside your custom factory, you will create the complete tree by hand, with plain old Java.
public object create(Type controllerType)
{
if (controllerType == typeof(HomeService))
return
new HomeService(
new PersonsRepositoryImpl(this.connectionString));
if (controllerType == typeof(BookService))
return
new BookService(
new BookRepositoryImpl(this.connectionString));
if (...)
throw new InvalidOperationException("Unknown type.");
}
My expectation is that JAX-RS contains a similar extension model, which allows you to practice Pure DI.
Thanks Steven for the answer. To conclude, this is the JAX-RS config where I am doing the DI:
public class AppConfig extends ResourceConfig {
public AppConfig() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-unit");
BookRepository bookRepository = new BookRepositoryImpl(emf);
BookService bookService = new BookService(bookRepository);
register(bookService);
}
}

asp.net 5 dependency injection in multiple projects

I've got an ASP.NET 5 dnxcore solution with some projects to separate my logic:
API
Core (with services for business logic)
DAL (repository interfaces)
Entity Framework (the repositories implementations)
Now I use DI to call my services in the constructors of my API controllers:
private readonly IMyService _myService;
public Controller(IMyService myservice){ _myService = myService; }
The services in my core get the repository thru constructor injection too:
private readonly IMyRepository _myRepo;
public MyService(IMyRepository myRepo){ _myRepo = myRepo; }
Currently I need to define my DI container in the startup class of my API to make it work.
My question is, how can I put the 'building' of the DI container of the repositories in my services in my Core-project. This way, my API is loosely coupled of the fact that my services use Entity Framework, so I can change to, for example, mongodb without changing my API project.
My question is, how can I put the 'building' of the DI container of the repositories in my services in my Core-project. This way, my API is loosely coupled of the fact that my services use Entity Framework, so I can change to, for example, mongodb without changing my API project.
You could, but you shouldn't do that.
Dependency Injection is the practice of making loosely-coupled classes throughout the libraries that can be plugged together (often in many ways).
However, each application should have a composition root, which is the one place in the application where we put the coupling code. Our first instinct as developers is to try to farm the coupling code off into its own library, but that is an urge that you should resist. See composition root reuse.
Mark Seeman's illustration sums it up well. Avoiding transitive dependencies is what is desired when using DI in order to flatten the dependency graph. This ensures assemblies can be used/tested in isolation without dragging along unnecessary dependencies, which in turn makes maintenance easier.
That said, many DI containers have a way to organize the configuration of certain parts of the application by using modules. In Autofac, the documentation for modules is here.
You can easily add an extension method of IServiceCollection into your services layer and use it to register its own dependencies.
Then in the startup you just call the method on the service layer without having any reference to EntityFramework in your web app.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace your.service.layer
{
public static class MyServiceCollectionExtensions
{
public static IServiceCollection AddMyServiceDependencies(this IServiceCollection services)
{
services.AddScoped<My.Data.Tier.DbContext, My.Data.Tier.DbContext>();
}
}
}
Startup:
using your.service.layer;
public void ConfigureServices(IServiceCollection services)
{
services.AddMyServiceDependencies();
}
Now your web app only needs a reference to your service layer and it is not directly dependent on EntityFramework.
As NightOwl888 have said, you should have a CompositionRoot in your application, the place where all your dependencies are set.
What I did is this:
1. Create a Core Class Library named CompositionRoot.
2. Add a class to handle your dependencies:
public class DependencyMapper
{
public static void SetDependencies(IServiceCollection serviceCollection, IConfigurationRoot configuration)
{
serviceCollection.AddEntityFramework()
.AddDbContext<SonoPeopleContext>(options =>
options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"])
);
MapperConfiguration mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new AutoMapperProfileConfiguration());
});
serviceCollection.AddSingleton<IMapper>(sp => mapperConfiguration.CreateMapper());
serviceCollection.AddScoped<IUserService, UserService>();
}
}
Then you reference your CompositionRoot in your MVC project and in your Startup.cs you just do
DependencyMapper.SetDependencies(services, Configuration);
That's all.
See this question, I have the same problem because my application is DB agnostic and base on the request will need to switch between a document oriented database (noSQL) and transaccional database (SQL).

Constructor Injection - Do we inject factories as well?

After listening to the Clean Code Talks, I came to understand that we should use factories to compose objects. So, for example, if a House has a Door and a Door has a DoorKnob, in HouseFactory we create a new DoorKnob and pass it to the constructor of Door, and then pass that new Door object to the constructor of House.
But what about the class that uses the House (say the class name is ABC)? It will depend on the HouseFactory, right? So do we pass the HouseFactory in the constructor of ABC? Won't we have to pass a whole lot of factories in the constructor that way?
Staying with the Door and DoorKnob example, you don't inject a factory - you inject the DooKnob itself:
public class Door
{
private readonly DoorKnob doorKnob;
public Door(DoorKnob doorKnob)
{
if (doorKnob == null)
throw new ArgumentNullException("doorKnob");
this.doorKnob = doorKnob;
}
}
No factories are in sight in this level.
House, on the other hand, depends on Door, but not on DoorKnob:
public class House
{
private readonly Door door;
public House(Door door)
{
if (door == null)
throw new ArgumentNullException("door");
this.door = door;
}
}
This keeps options open until at last you have to compose everything in the application's Composition Root:
var house = new House(new Door(new DoorKnob()));
You can use a DI Container to compose at this level, but you don't have to. No factories are involved.
If you inject too many factories that is a code smell called constructor over-injection that indicates your class is doing too much.
Many containers provide a feature called auto-factories. That means they generate factories of type Func<T>automatically if they know how to generate T.
Castle Windsor has an advanced feature called Typed Factory facilities which generates implementations of a factory interface on-the-fly.
There is also a port of typed factories for Unity in the TecX project.
If you end up using Unity, I have recently implemented an equivalent of Castle Windsor Typed Factories for Unity. You can find the project at https://github.com/PombeirP/Unity.TypedFactories, and the NuGet package at http://nuget.org/packages/Unity.TypedFactories.
The usage is the following:
unityContainer
.RegisterTypedFactory<IFooFactory>()
.ForConcreteType<Foo>();
You just have to create the IFooFactory interface with a method returning IFoo, and the rest is done for you by the library. You can resolve IFooFactory and use it to create IFoo objects straight away.

Can someone explain how Castle Windsor is working in my app?

I have begun using Castle Windsor and somehow my app is all up and running but I dont really understand how its working. Don't refer me to the documentation as I wouldn't be here otherwise.
In my Global.asax.cs I have this:
private static IWindsorContainer container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
BootstrapContainer();
}
protected void Application_End()
{
container.Dispose();
}
private static void BootstrapContainer()
{
container = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
Now this is registering a new controller factory which I understand. The installation of a WindsorContainer from the current assembly I think registers all installers for example I have a repository installer. I assume that the container that is created in Global.asax is passed to the installers.
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.Where(type => type.Name.EndsWith("Repository"))
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.PerWebRequest));
}
}
In my controller I have created a constructor and passed in a IRepository argument. What I dont understand is how the controller accepts this argument.
Secondly as a test I created 2 repository classes that implement a IRepository. Putting a breakpoint in the controller constructor it passes in one of these classes. How do I map what class that implements IRepository should be passed to the constructor?
I also have Fluent NHibernate up and running. For the next stage I would like the IRepository to have a dependency on the ISession. How do I do that?
Thanks for your help
Since you have registered a controller factory that uses Windsor, it is the Windsor IoC container that is responsible for resolving all your controller instances as and when they are needed.
That is, when you access a URL in your MVC project that points to the action "Index" on your "HomeController" your WindsorControllerFactory will be asked, by the MVC framework, for an instance of HomeController.
If that controller has a constructor which takes an instance of IRepository and you have registered IRepository as a service with the container then Windsor will know how to satisfy the dependency of the HomeController class. Therefore it can first resolve IRepository into some concrete class, instantiate this, and pass it in as a parameter to the HomeController constructor before returning the instance of HomeController to the MVC framework.
If you need different implementations of IRepository for different purposes (i.e. a UserRepository and a ProductRepository) you could create separate interfaces for these, each of which extend IRepository, e.g.:
public interface IProfileRepository : IRepository {}
Then you can use Windsor's fluent registration API to register all concrete classes that implement IRepository, and have them registered by the specific service they provide, e.g. IProfileRepository.
If you do this, Windsor will automatically resolve all instances that implement IRepository for you without you having to write any new registration code when you add a new implementation.
As for making your repository classes depend on ISession, you can do this in a number of ways. I would recommend not letting them depend directly on a session, but rather let them depend on a class through which they can obtain the current session (so that you can share sessions between repositories). There's lots of information on why this is good practice out there on the web, just do a search.
Now, as for actually making it happen, you can either:
Register an instance of a class (by interface) that will retrieve a session for you with Windsor and let Windsor resolve this class as a parameter to your repository constructors.
Register ISession with Windsor and use a factory method to retrieve it when it is resolved.

Dependency Injection and ModelStateWrapper

in tutorial Validating with a service layer constructor for Product Service looks like this:
ProductService(IValidationDictionary validationDictionary, IProductRepository repository)
and its instance in default controller constructor is created like this:
public ProductController()
{
_service = new ProductService(new ModelStateWrapper(this.ModelState), new roductRepository());
}
If I want to use Unity for DI, second constructor should obviously be used.
public ProductController(IProductService service)
{
_service = service;
}
But then I do not not know to configure Unity to inject first parameter of ProductServise,because ModelStateWrapper uses ModelState from controller, which is created inside controller and cannot be injected.Is it possible to inject such dependency to ProductService?
Think.
Here's what you're trying to do:
In order to create product controller you need product service
in order to create product service you need product controller
you have a vicious circle, that's why you can't do it.
I dunno about implementation Unity, but conceptually, you need to break the circle, like this:
create product controller without passing product service to it
create product service and pass product controller's model state to it
inject product service into product controller via property injection
AFAIK unity does support property injection, but it requires you to put attribute onto the property. If I were you, I'd consider using a less invasive container (pretty much any other is better).

Resources