Reputation: 197
Quick Dependency Injection / IoC Container question that will hopefully be an easy one for a seasoned developer. I am newer to DI, and have the basics of the process down for registering the types and resolving them for building the instances using constructor injections, but have a question about the process for loading their instances with data and when/where to do that correctly.
So if you have an object that has been resolved to build the object with the DI container - it will load a hollow object, but at what point are you suppose to load the object with its needed data?
For Example: If you have a IPerson interfaces that is implemented by Student class, and Principal class. And you have a ISiteVisit interface that is implemented by SiteVisit and you resolve in the following fashion:
var dictr = new UnityContainer();
dictr.RegisterType<IPerson, Principal>();
dictr.RegisterType<IVisitSite, SiteVisit>();
var siteVisit = dictr.Resolve<IVisitSite>();
siteVisit.Visit();
Where would you load up the details for the Person (in the example class is: Principal) for data such as FirstName, LastName, PhoneNumber, Address, etc.. - anything relevant to the Person? Would it be loaded in the constructor, if not what is the best place to load it, best convention and/or best practices?
Should you ideally use Dependency Injection with every Interface in your application, or just certain models?
How do you load data into the resolved objects when you are using Dependency Injection?
Environment: Visual Studio 2015, C#, Unity for DI / Container (using Console app for testing this)
Upvotes: 1
Views: 3651
Reputation: 172646
Dependency Injection is the practice of composing graphs of loosly coupled components. Components are the classes in your application that contain its behavior.
Dependency Injection is not meant to build up objects that merely contain data. Using Dependency Injection we build an graph of components. After that graph has been build (using constructor injection), we pass runtime data through this graph by making method calls on that constructed graph of objects.
Your Person
class is clearly runtime data since it contains data like FirstName
and LastName
. A person is not a component (it does not contain behavior). It is either a Data Transfer Object (DTO) or an Entity. Although entities might contain behavior (when practicing Domain-Driven Design), this behavior is never hidden behind abstractions, because this is the logic that the rest of the application is built around.
So a typical way to load entities is using the Repository Pattern. A repository is a component, which is capable of loading and saving entities of a certain kind. For instance:
public interface IPersonRepository
{
Person GetById(Guid id);
}
public class SqlPersonRepository : IPersonRepository
{
public GetById(Guid id) => // implementation here
}
Now we can register this component as follows:
container.RegisterType<IPersonRepository, SqlPersonRepository>();
Upvotes: 6
Reputation: 91
I usually use the Factory pattern or Repository pattern to handle creating and maintaining entities such as Person.
I Generally use Dependency Injection to compose the service classes that implement these patterns.
For example:
var dictr = new UnityContainer();
dictr.RegisterType<IPersonFactory, PersonFactory>();
dictr.RegisterType<IVisitSite, SiteVisit>();
var personFactory = dictr.Resolve<IPersonFactory>();
IPerson person = personFactory.CreatePrincipal(your args here);
var siteVisit = dictr.Resolve<IVisitSite>();
siteVisit.Visit(person);
Hope that helps.
Upvotes: 2