I am starting to work with DI/IoC and I have some troubles understanding all the concepts.
I have chosen Autofac because it seems it's one of the few that supports both .Net 4.6+ and .Net Core. It seems it also most widely used.
1) Constructor injection - for e.g. in Controllers or my WCF services I understand that it is impossible to do constructor injection to an object that I am instantiating in my code, meaning it is not automatically instantiated.
2) Property injection I would like to do something similar to how you do it in Ninject:
[Inject]
public IWeapon Weapon { get; set; }
And as I understund, in Autofac. it is equivelanet to:
builder.RegisterType<Weapon>().As<IWeapon>().PropertiesAutowired();
1. Now, why is the constructor injection the preferred way?
For example, I have:
- Factory for repositories
- Factory for business engines
Those factories, are just one-liners that should do something like (from another IoC):
public class DataRepositoryFactory : IDataRepositoryFactory
{
T IDataRepositoryFactory.GetDataRepository<T>()
{
return ObjectBase.Container.GetExportedValue<T>();
}
}
Some methods require both, some do not. Doing something like:
public SampleControllerOrManager(IUnitOfWork unitOfWork, IRepositoryFactory repositoryFactory, IBusinessEngineFactory engineFactory)
seems like a waste of resources.
I understand that this helps with testing (?).
But this looks cleaner:
public SampleControllerOrManager(IUnitOfWork unitOfWork)
[Inject]
public IRepositoryFactory RepositoryFactory { get; set; }
[Inject]
public IBusinessEngineFactory EngineFactory { get; set; }
2. Injecting Entity Framework DbContext into the repositories
I want to register the context with the Container and have that injected into the object constructors of the UnitOfWork and the Repository's. I want to be sure the same instance is injected into all the objects. How do I do it in Autofac?
public class Repository : IRepository {
//context injected here
public Repository (DbContext context){ ... }
}
public class Manager {
public void SomeMethod(){
IRepository = RepositoryFactoryGetDataRepository<ISomeTypeRepository>
}
}