Ninject factory management - dependency-injection

I'm using Ninject.Extensions.Factory to control the lifecycle of the repository layer. I want to have a single point of reference from which I can get a reference to all repositories and have them lazily available. Ninject Factory approach seems like a good solution but I'm not too sure about my solution:
public class PublicUow : IPublicUow
{
private readonly IPublicRepositoriesFactory _publicRepositoriesFactory;
public PublicUow(IPublicRepositoriesFactory publicRepositoriesFactory)
{
_publicRepositoriesFactory = publicRepositoriesFactory;
}
public IContentRepository ContentRepository { get { return _publicRepositoriesFactory.ContentRepository; } }
public ICategoryRepository CategoryRepository { get { return publicRepositoriesFactory.CategoryRepository; } }
}
The problem lies in the PublicRepositories class.
public class PublicRepositoriesFactory : IPublicRepositoriesFactory
{
private readonly IContentRepositoryFactory _contentRepositoryFactory;
private readonly ICategoryRepositoryFactory _categoryRepositoryFactory;
public PublicRepositoriesFactory(IContentRepositoryFactory contentRepositoryFactory, ICategoryRepositoryFactory categoryRepositoryFactory)
{
_contentRepositoryFactory = contentRepositoryFactory;
_categoryRepositoryFactory = categoryRepositoryFactory;
}
public IContentRepository ContentRepository { get { return _contentRepositoryFactory.CreateContentRepository(); } }
public ICategoryRepository CategoryRepository { get { return _categoryRepositoryFactory.CreateCategoryRepository(); } }
}
I'm worried that this will become hard to manage as the number of repositories increases, this class might at some point need to have around 20-30 constructor arguments with the current implementation.
Is there an approach I can take to reduce the number of ctr arguments, like passing an array/dictionary of interfaces or something similar?
I've thought about using property injection in this scenario but most articles suggest avoiding property injection in general.
Is there maybe a more general pattern that would make this easier to manage?
Is this in general a good approach?

It has become rather common practice to use a repository interface like
public interface IRepository
{
T LoadById<T>(Guid id);
void Save<T>(T entity);
....
}
instead of a plethora of specific repositories like IContentRepository, ICategoryRepository,..
specific repositories are only ever useful in case of having specific logic to the entity type and an operation, for example verifying that it's valid. But such operations are rather an "aspect" or a cut-through-concern which you should model as such. Managing/doing validation on save should not be implemented x-times but only once. The only thing you should specifically implement are the exact validation rules (DRY). But these should be implemented in separate classes and used by composition, not inheritance.
Also, for stuff like retrieving an entity or multiple entities "based on a use case", you should use specific query classes, and not put methods on a repository interface (SRP, SOC). An example would be GetProductsByOrder(Guid orderId). This should be neither on the Products nor the Order Repository but rather in a separate class itself.
Taking things a step further, it does not seem a good idea to use a factory to late create all repositories. Why?
makes software more complex (thus harder to maintain and extend)
usually negligible performance gain
deteriorates testability
also see Mark Seeman's blog post Service Locator is an anti pattern, where he's also talking about the disadvantages of late-creation vs. the composition of the entire object graph in one go.
I'm not trying to say that you should never use factory/lazy, but only when you've got a really good reason to :)
Example of a query
I'm not very familiar with EntityFramework. I know NHibernate a whole lot better, so behold.
public class GetParentCategoriesQuery : IGetParentCategoriesQuery
{
private readonly EntityFrameworkContext context;
public GetParentCategories(EntityFrameworkContext context)
{
this.context = context;
}
public IEnumerable<Category> GetParents(Category child)
{
return this.context.Categories.Where(x => x.Children.Contains(child));
}
}
So basically the only thing you change is extracting the GetParentCategoriesQuery into it's own class. The DbContext instance must be shared with the other query and repository instances. For web projects, this is done by binding the DbContext .InRequestScope(). For other applications you may need to use another machanism.
The usage of the query would be quite simple:
public class CategoryController
{
private readonly IRepository repository;
private readonly IGetParentCategoriesQuery getParentCategoriesQuery;
public CategoryController(
IRepository repository,
IGetParentCategoriesQuery getParentCategoriesQuery)
{
this.repository = repository;
this.getParentCategoriesQuery = getParentCategoriesQuery;
}
public void Process(Guid categoryId)
{
Category category = this.repository.LoadById(categoryId);
IEnumerable<Category> parentCategories =
this.getParentCategoriesQuery(category);
// so some stuff...
}
}
An alternative to the scoping is to have the repository instantiate the the query type and pass the DbContext to the query instance (this can be done using the factory extensions):
public TQuery CreateQuery<TQuery>()
{
return this.queryFactory.Create<TQuery>(this.context);
}
which would be used like:
IEnumerable<Category> parents = repository
.CreateQuery<GetParentCategoriesQuery>()
.GetParents(someCategory);
But please note that this alternative will again only late-create the query and thus result in less testability (binding issues may be remain undetected for longer).
The GetParentCategoriesQuery is part of the repository layer, but not part of the repository class.

Related

Entity framework 6 providing repositories and UoW out of the box

But how do you use it?
I have a Code First project set up, and trying out some stuff with this new EF6. Reading all kinds of posts/blogs from at least 2 years old about EF4/5. But nothing whatsoever about EF6.
Let's say I have these entities:
public DbSet<Person> Persons { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Invoice> Invoices { get; set; }
Do I still need to create repositories for each entity? Or would a class suffice with some methods to do some custom calculations aside from CRUD?
I know that this line:
kernel.Bind<MyDbContext>().ToSelf().InRequestScope();
Would suffice for DI, and that it will inject via constructor to upper layer classes where applicable.
The project has a class library and a web project asp.net-mvc. Where the class lib project contains my entities and has Migrations enabled.
Any light on this matter is really appreciated.
I've added a Repository layer on top of EF (which utilizes both Repository and UoW patterns inherently in its construction) in a couple of projects, and I've done that with one class that utilizes generics so that I only needed one file for all of my entities. You can decide if you want to do it or not, but I've found it useful in my projects.
My repositories have typically started out like what I've shown below, following up with more extension methods if/when I come across a need for them (obviously I'm not showing all of them, that's up for you to decide how to implement your repository).
public class Repository<T> : IRepository<T> where T : class
{
protected IDbContext Context;
protected DbSet<T> DbSet { get { return Context.Set<T>(); } }
public Repository(IDbContext context = null)
{
Context = context ?? new DbContext();
}
public void Add(T newRecord)
{
DbSet.Add(newRecord);
}
public void Update(T record)
{
var entry = Context.Entry(record);
DbSet.Attach(record);
entry.State = EntityState.Modified;
}
public void Remove(T record)
{
Context.Entry(record).State = EntityState.Deleted;
DbSet.Remove(record);
}
public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
public bool Contains(Expression<Func<T, bool>> predicate)
{
return DbSet.Count(predicate) > 0;
}
public int Count(Expression<Func<T, bool>> predicate)
{
return DbSet.Count(predicate);
}
public int Save()
{
return Context.SaveChanges();
}
}
I've used repositories for 2 main reasons:
Unit testing. Doing this pattern allows me to fake the underlying data without having to have bad data in my database. All I need to do is simply create another implementation of IRepository that uses an in-memory list as its data source, and I'm all set for my pages to query that repository.
Extensibility. A fair number of times I've put in some methods into my repository because I found myself constantly doing the same logic with queries in my controllers. This has been extremely useful, especially since your client-side code doesn't need to know how it's doing it, just that it is doing it (which will make it easier if you need to change the logic of one file vs. multiple files).
This not all of it, obviously, but that should be enough for this answer. If you want to know more on this topic, I did write a blog post on it that you can find here.
Good luck on whatever you decide to do.
Entity Framework in itself can be considered a Repository. It facilitates work with data, in this case a database. This is all that a Repository does.
If you want to build another Repository on top of what EF provides, it is completely up to you - or to your business rules.
Many complex projects uses 2-3 layers of repositories with web services between. The performance is lower but you gain on other plans like security, resilience, separation of concerts, etc.
Your company might decide that it's in their best interest to never access data directly from front-end projects. They might force you to build a separate web-service project, which will be accessible only from localhost. So you will end up having EF as Repository in the webservice project. On the front-end side you will obviously need to build another Repository which will work with the web-service.
It also depends a lot of your project. If it's a small project it really it's overkill to build a second Repository on top of EF. But then again, read above. Nowadays security matters a lot more than performance.
To be politically correct I'm including the comment made by Wiktor Zychla:
"DbSet is a repository and DbContext is a Unit of Work. "Entity Framework is a Repository" could lead to unnecessary confusion."

Creating new repositories with each controller

I've been reading up on Dependency Incection, UnitOfWork and IRepository patterns, and I intend to implement them all as I go along. But it's all a lot to take in at once. Right now I just want to make sure about some basic things, and that I'm not missing anything crucial that could impact my application.
The application is rather small and there will be no more than 10 simultaneous users at any given point.
The AdressRegDataContext is the dbml generated (using Visual Studio Add -> Linq to SQL classes).
My question concern the adding of the second controller below:
Are there any problems creating a new repository in each controller like this?
To me it feels like two users would have two different contexts if they are using the application at the same time. Or do the datacontext handle that for me? A singleton repository makes sense theoretically, but I've read that that's a big nono so I won't do that.
I have a repository that I use:
Repository
namespace AdressReg.Models
{
public class AdressRegRepository
{
private AdressRegDataContext db = new AdressRegDataContext();
// Return person by id
public Person GetPerson(int id)
{
return db.Persons.SingleOrDefault(p => p.id == id);
}
// Return student by id
public Student GetStudent(int id)
{
return db.Students.SingleOrDefault(s => s.id == id);
}
}
}
So far I've only been using the one controller:
HomeController
namespace AdressReg.Controllers
{
public class HomeController : Controller
{
AdressRegRepository repository = new AdressRegRepository();
// GET: /Home/Person
public ActionResult Person(int id)
{
PersonView view = new PersonView();
view.person = repository.GetPerson(id);
return View(view);
}
}
}
But I was planning on adding another:
EducationController
namespace AdressReg.Controllers
{
public class EducationController: Controller
{
AdressRegRepository repository = new AdressRegRepository();
// GET: /Education/Student
public ActionResult Student(int id)
{
StudentView view = new StudentView();
view.student = repository.GetStudent(id);
return View(view);
}
}
}
Yes they are. First of all that's not a 'true' repository, that is a useless abstraction on top of EF, you can ditch it. A repository should return busines or app objects not EF entities. For querying purposes it should return at least some bits (if not all ) of the view model. So, it should return a PersonView or a StudentView. These are guideliness not the absolute truth or rules, but you really need to be aware of the purpose of a design pattern, in this case the Repository. And your code shows you haven't understood it yet.
In your app, the repo doesn't do anything useful, so use the ORM directly, it's much simpler.
Your controllers are tightly coupled to a specific concrete repository. The point is you should define an abstraction and pass that as a dependency in the constructor. Something like
// a better name is needed, this would be a query repository
public interface IAddressesRegRepository
{
StudentView Get(int it);
}
public class MyController:Controller
{
IAddressesRegRepository _repo;
public MyController(IAddressesRegRepository repo)
{
_repo=repo;
}
public ActionResult Student(int id)
{
StudentView view = _repo.GetStudent(id);
return View(view);
}
}
As you see, the controller now depends on an abstraction, the DI Container will inject a concrete implementation when the controller is created. It will allow you to mock repositories and to have multiple implementations. Same approach is for everything you want to use in the controller.
About repositories, I do prefer to have different business/ query repositories (though nowadays I'm using query handlers) i.e I don't put querying behaviour on a domain repository unless it's needed by the business layer itself.
For strictly querying, it's much straight forward to use EF or if your queries are ugly or want to change implementation later, use a query object/ repository/service/handler (call it however you want) that will construct the view model from persistence. The point is to keep the persistence details (ORM, EF Entites) in the DAL, your UI shouldn't know about them. In your example, the UI knows about EF entites.
Once again, what I've said are guidelines, when you get more experienced you'll know when to bend (break) them without nasty side effects.

How can I inject the Repositories to the UnitOfWork?

I've implemented my UnitOfWork so that it keeps references to all repositories.
public interface IUnitOfWork
{
void Commit();
void RollBack();
}
public interface IMyUnitOfWork : IUnitOfWork
{
IFooRepository Foos { get; }
IBarRepository Bars { get; }
// Other repositories ...
}
Note that the repositories implements a generic type of repository interface.
public interface IFooRepository : IRepository<Entities.Foo>
{
// FooRepository specific methods goes here.
}
public interface IRepository<T> : IRepository
where T : class
{
}
Now how can I inject these repository to my UnitOfWork. Of course I want them with a lazy loading behavior. For example:
public class ConcreteUnitOfWork : IMyUnitOfWork
{
private readonly IUnityContainer unityContainer;
private IFooRepository fooRepository;
public ConcreteUnitOfWork(IUnityContainer unityContainer)
{
this.repositoryFactory = repositoryFactory;
}
public IFooRepository Foos
{
get
{
return this.fooRepository ??
(this.fooRepository = unityContainer.Resolve<IFooRepository>());
}
}
}
I know passing the Unity container to the UnitOfWork is incorrect but what pattern would you offer to solve this issue?
You may mention that I shouldn't keep the repository references in the UnitOfWork but please suppose a service class which needs several repositories. With this design I can just pass the UnitOfWork as the constructor parameter (Constructor Injection) to the service class, but if I didn't keep the repository references in UnitOfWork, I would have to pass all needed repositories as constructor parameters and you know what it leads to.
-- UPDATE --
Please let me know if I'm absolutely wrong and I should never compose the repositories in UnitOfWork. Then please give me a solution about "Constructor Over-injection" here.
-- UPDATE2 --
It seems that composing (referencing to) the repositories from UnitOfWork breaks the Open/Closed principle as we need to change the UnitOfWork class when we add a new repository (add a new property).
If it's right then I should consider a refactoring. Would you please give me some ideas?
It seems as though the current design proposal mixes more than one responsibility into the IMyUnitOfWork interface. You say that this is because otherwise a service class might need to take each Repository independently. I'm assuming you mean something like this:
public MyService(
IUnitOfWork uow,
IFooRepository fooRepository,
IBarRepository barRepository)
This seems to me to be a much simpler and cleaner design.
But then what about Constructor Over-injection?
Well, there's that... but the thing is that this is exactly the same problem you now have with your ConcreteUnitOfWork implementation. You haven't solved the Constructor Over-injection smell at all - you've just moved it to another class.
Actually, by moving it to ConcreteUnitOfWork you've made it more difficult to deal with the situation. Because ConcreteUnitOfWork is a pure infrastructure class (or a support class, if you will) it doesn't have any business context, so it's really hard to suggest a way resolve the Constructor Over-injection smell here.
On the other hand, a given Service (or perhaps a Controller) would tend to be more specialized and have knowledge of the business context, so it wouldn't need every repository in order to do its job - or if it does, it probably attempts to do too much.
Such a specific business component can better be refactored to a Facade Service.

Repository Pattern pros and cons of each implementation

Hi looking at the repository pattern which commonly seems to be implemented something like:
public class GenericRepository<TEntity> where TEntity : class
{
// other business
public virtual TEntity GetByID(object id)
{
return db.Set().Find(id);
}
public virtual void Insert(TEntity entity)
{
db.Set().Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = db.Set().Find(id);
Delete(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
db.Set().Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
So for every type you want to work with (ie update) you need to instantiate a repository.
So if I had two types I wanted to save Cars and Trucks I would need to go:
var carRepository = new GernericRepository<Car>();
carRepository.Update(myCar);
var truckRepository = new GernericRepository<Truck>();
carRepository.Update(myTruck);
So then you have seperate repositories for each type. To make sure you save everything at once you need the unitOfWork to ensure they all use the same context and save at one time.
Surely wouldn't it be better to have something like:
public class GenericRepository
{
// other business
public virtual TEntity GetByID<TEntity>(object id) where TEntity : class
{
return db.Set<TEntity>().Find(id);
}
public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
{
db.Set<TEntity>().Add(entity);
}
public virtual void Delete<TEntity>(object id) where TEntity : class
{
TEntity entityToDelete = db.Set<TEntity>().Find(id);
Delete(entityToDelete);
}
public virtual void Update<TEntity>(TEntity entityToUpdate) where TEntity : class
{
db.Set<TEntity>().Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
This means the repository only needs to be instantiated once and therefore is truely generic?
So you could update your cars and trucks like this:
var repository = new GernericRepository<Car>();
repository.Update<Car>(myCar);
rRepository.Update<Truck>(myTruck);
Surely this is a better method? Am I missing something? It automatically has only one context too.
The repository pattern does not decouple the data access from the data store, that is what the ETL tool such as NHibernate or the Enity Framework does for. The repository pattern provides reusable methods for extracting data.
I have previously used a so called "Generic" repository as you have described and thought it was great. It isn't until you realise that you have just put another layer on top of NHibernate or the Entity Framework you realise it's all gone Pete Tong.
Ideally what you want are interfaces that describe ways of getting data out of your data store and should not leak what data access you are using. For example:
public interface IEmployee
{
IEmployee GetEmployeeById(Guid employeeId);
IEmployee GetEmployeeByEmployeeNumber(string employeeNumber);
IEnumerable<IEmployee> GetAllEmployeesWithSurname(string surname);
IEnumerable<IEmployee> GetAllEmployeesWithStartDateBetween(DateTime beginDateTime, DateTime endDateTime);
}
This gives you a contract to code to, there is no knowledge of your persistence layer and the queries used to retrieve the data can be unit tested in isolation. The interface could inherit from a base interface that provides common CRUD methods but you would be assuming that all your repositories would need CRUD.
If you go down the road of a Generic Repository you will end up with duplication in your queries and you will find it much harder to unit test the code that uses the repository as you will have to test the queries as well.
Generics by itself does not make an implementation of the repository pattern. We've all seen the generic base class used in example repository pattern implementations but this is to make things DRY (Don't-Repeat-Yourself) by inheriting from the base class ( GenericRepository in your case) to more specialized child classes.
Only using the generic, base class GenericRepository assumes that your repositories will only ever need the most basic CRUD methods. For a more complex system, each repository becomes more specialized based on underlying business entities data requirements.
Also, you will need to have interfaces that define your data contracts with your other layers. Using the repository pattern means you don't want to expose your concrete implementations of your repositories to your other layers.

Constructor Injection and when to use a Service Locator

I'm struggling to understand parts of StructureMap's usage.
In particular, in the documentation a statement is made regarding a common anti-pattern, the use of StructureMap as a Service Locator only instead of constructor injection (code samples straight from Structuremap documentation):
public ShippingScreenPresenter()
{
_service = ObjectFactory.GetInstance<IShippingService>();
_repository = ObjectFactory.GetInstance<IRepository>();
}
instead of:
public ShippingScreenPresenter(IShippingService service, IRepository repository)
{
_service = service;
_repository = repository;
}
This is fine for a very short object graph, but when dealing with objects many levels deep, does this imply that you should pass down all the dependencies required by the deeper objects right from the top? Surely this breaks encapsulation and exposes too much information about the implementation of deeper objects.
Let's say I'm using the Active Record pattern, so my record needs access to a data repository to be able to save and load itself. If this record is loaded inside an object, does that object call ObjectFactory.CreateInstance() and pass it into the active record's constructor? What if that object is inside another object. Does it take the IRepository in as its own parameter from further up? That would expose to the parent object the fact that we're access the data repository at this point, something the outer object probably shouldn't know.
public class OuterClass
{
public OuterClass(IRepository repository)
{
// Why should I know that ThingThatNeedsRecord needs a repository?
// that smells like exposed implementation to me, especially since
// ThingThatNeedsRecord doesn't use the repo itself, but passes it
// to the record.
// Also where do I create repository? Have to instantiate it somewhere
// up the chain of objects
ThingThatNeedsRecord thing = new ThingThatNeedsRecord(repository);
thing.GetAnswer("question");
}
}
public class ThingThatNeedsRecord
{
public ThingThatNeedsRecord(IRepository repository)
{
this.repository = repository;
}
public string GetAnswer(string someParam)
{
// create activeRecord(s) and process, returning some result
// part of which contains:
ActiveRecord record = new ActiveRecord(repository, key);
}
private IRepository repository;
}
public class ActiveRecord
{
public ActiveRecord(IRepository repository)
{
this.repository = repository;
}
public ActiveRecord(IRepository repository, int primaryKey);
{
this.repositry = repository;
Load(primaryKey);
}
public void Save();
private void Load(int primaryKey)
{
this.primaryKey = primaryKey;
// access the database via the repository and set someData
}
private IRepository repository;
private int primaryKey;
private string someData;
}
Any thoughts would be appreciated.
Simon
EDIT:
Opinion seems to be that the injection should start at the top layer. ActiveRecord would be injected into ThingThatNeedsRecord which is injected into OuterClass.
The problem with this would be that if ActiveRecord needs to be instantiated with a run-time parameter (the id of the record to retrieve for example). If I'm injecting ActiveRecord into ThingThatNeedsRecord right at the top, I somehow have to figure out what id needs to be at that point (which exposes the top layer to implementation which it shouldn't) or I have to have a partially constructed ActiveRecord and set the Id later on. This becomes more complicated if I need N records and won't know until execution of logic inside ThingThatNeedsRecord.
Inversion of Control is like violence. If it doesn't solve your problem, you're not using enough of it. Or something like that.
More to the point, I think your OuterClass should have ThingThatNeedsRecord injected into it via constructor injection. Likewise ThingThatNeedsRecord should have ActiveRecord injected into it. Not only will this solve your immediate problem, but it will make your code more modular and testable as well.

Resources