Generic repository, DI, Aggregation Roots - c#

Having a generic repository like
public class Repository<T>
where T: Entity<T>
{
/*anything else*/
}
should concrete repositories per agregation root like
class ProductRepository : Repository<Product>
{
}
class CategoryRepository : Repository<Category>
{
}
be created?
Also how do I use DI (Ninject) with generic implementation of repository.
Samples are apreciated!
Thanks!

I see a lot of misuse of generics in the questions in SO and while it does not necessarily refer to your question (although it will help to clarify), I think once for all write a summary here.
Generics is a typeless reuse of the behaviour (almost, since you can limit the types using restrictions). If a behaviour is shared by all types (or those limited to restrictions) you use the generics.
However if implementation of each generic type needs to be individually implemented, then using generics does not help and is reduced to a decoration - and for me it is bad design.
OK, let's have an example:
interface IConverter<T1, T2>
{
T1 Convert(T2 t2);
}
This looks like a good generics (converting one type to another), but I have to implement all such combinations of types as different converters. And a IConverter<Apple, Orange> does not make any sense. Hence generics here is misleading and BAD.
Now going back to repositories. There are 100s of articles on this particular issue (lots of controversies) but this is personal my take:
Usually it is not recommended to use generic repositories. However, in my personal experience I use generic repository to implement common stuff (implemented by a base repo) and then use individual ones if there is any additional:
interface IRepository<T>
{
T GetById(int id);
IEnumerable<T> GetAll();
void Save(T t);
}
class BaseRepository<T> : IRepository<T>
{
... // implement common methods
}
interface IProductRepository : IRepository<T>
{
IEnumerable<T> GetTop5BestSellingProducts();
}
class ProductRepository : BaseRepository<T>, IProductRepository
{
... // implement important methods
}
NOTE
Some believe repository must allow for criteria to be passed to the repository (Eric Evans DDD book) but I again do not feel I have to agree to that. I prefer a domain-significant declaration on the repository (e.g. GetTopFiveBestSellingProducts or GetTopBestSellingProducts) unless there are 100s of such like in a report writer which is only 1% of cases.
Second question:
I do not use Ninject but for any DI, here is how you do it
// PSEUDOCODE !!!
container.Register<IProductRepository , ProductRepository>();
depending on DI framework, it can be slightly different.

Related

Should we use an interface as dependency (in ctor) even if what we expect is one specific implementation?

Let's say we have a class, for example SqlIdProvider, that needs an SQL repository to perform some operations. We also have an SqlRepository class that implements an IRepository interface like follows:
public interface IRepository {
// All repository methods here.
}
public sealed class SqlRepository : IRepository {
// All repository methods here.
}
public sealed class SqlIdProvider {
private IRepository _repository;
public SqlIdProvider(IRepository repository){
_repository = repository;
}
}
The SqlIdProvider has a strong dependency on SqlRepository, so it will not work if I provide, for example, an instance of the following class:
public sealed class MongoRepository : IRepository {
// All repository methods here.
}
However, the signature of SqlIdProvider tells me that I could just provide one of these and everything should be fine.
In this situation, I usually think of three options:
1) Keep as is, and hope that the name will be enough for others to know that you shouldn't provide a MongoRepository to an SqlIdProvider (though not enforcing it in any way).
2) Change the SqlIdProvider constructor to take the concrete SqlRepository. This would enforce the requirement, but it would difficult unit testing, forcing us to remove the sealed keyword from SqlRepository to be able to fake the implementation (btw, I like classes to be sealed unless there's a good reason not to).
3) Create an empty interface that extends IRepository, designated for the sole purpose of SQL repositories, called ISqlRepository. Now, we could change the SqlIdProvider constructor to take the ISqlRepository interface instead.
public interface ISqlRepository : IRepository {
// This one is empty on purpose.
}
To me, option 3) seems to be the most appealing, however still feels a like I'm doing something wrong here by creating an empty interface.
Is there any better way we can be explicit with the constraint and at the same time allow easy unit testing?

Real-world examples with subtyping constraints in .NET generics

Are there any real-world examples of using subtyping constraints on type parameters in .NET generics? By «subtyping constraints» I mean
where T : <base class name>
and
where T : U
May be there are some standard generics with corresponding constraints? Or specialized generic .NET-libraries.
UPD There are lots of good examples with interface constraints
where T : <interface name>
But subtyping constraints seems to be very specific and not so useful. I try to understand, in which cases this kind of constraints is really crucial. Luaan's answer contains examples with where T : <base class name> from ASP.NET MVC, but I am still interested in real-world examples with where T : U constraint.
I use them for a repository class in my data access layer e.g.
public interface IRepository<T>
where T : IDbItentity
{
IList<T> GetAll();
T GetById(int id);
int Insert(T saveThis);
void Update(T updateThis);
void Delete(T deleteThis);
}
Where IDBItentity is an interface as follows:
public interface IDbItentity
{
int Id { get; }
}
It's something you use a lot. In a way, it immitates the way normal inheritance works.
So for example, if you've got a common functionality built around O/RM entities, you can just create an entity base class, and use that as a type constraint in all the various data layers manipulating that entity.
Extremely useful is its use with interfaces.
And very often, you're going to write some kind of a wrapper around something else.
The basic idea is that you use those when you really only want the type parameter to fit some use case, but rather than just using the interface, you let the user of your code supply their concrete type. It still implements all the stuff you need to work correctly, but at the same time, the user can use all the features, even those you don't know about.
You will not find many cases in the BCL. Basically, this has to do with the fact that type constraints are constraints. The BCL usually uses generic types and methods to write very general functionality - I guess that's in part because of the fact that most of the BCL was there before generics, and because most of the time, inheritance will work just as well, if not better.
There's still differences, though. Say you need a collection of some entities. If you just use List<Entity>, you're saying "I expect any entity whatsoever, thanks". If you use List<T> where T : Entity (pseudocode), you're saying "I need to know the type you're giving me is an Entity, but I only want one kind of entity in the whole collection".
All in all, if you want good applications of generic type constraints, look at newer code. For example, in ASP.NET MVC, there's things like this:
public abstract class CachedAssociatedMetadataProvider<TModelMetadata>
: AssociatedMetadataProvider
where TModelMetadata : ModelMetadata
public class DataAnnotationsModelValidator<TAttribute>
: DataAnnotationsModelValidator
where TAttribute : ValidationAttribute
It's also very useful when you're using Actions (or events) to tag functionality to some such general class from the outside.
Again, the uses are basically such:
Constraint the types that can be used in your class
Ensure the type passed to you conforms to some contract
Improve useability for the users of your code
Performance optimization of value-types, mostly avoiding boxing - e.g. you can use IComparable without having to box the value
Often it is used for extension methods, for example:
public static string Parse<Tenum>(this object spr, int id) where Tenum : struct, IConvertible
{
Contract.Ensures(typeof(Tenum).IsEnum, "type must be is enum");
return ((Tenum)(object)id).ToString();
}
string ProductTypeTitle = this.Parse<ProductType>(product.ProductTypeID);

Programming against an interface with only one class implementing said interface

I can understand why to program against an interface rather than an implementation. However, in an example like the following (I find this a lot):
public interface ISomething
{
void BlahOne(int foo);
void BlahTwo(string foo);
}
public class BaseSomething : ISomething
{
public void BlahOne(int foo)
{
//impl
}
public void BlahTwo(string foo)
{
//impl
}
}
public class SpecificSomethingOne : BaseSomething
{
public void SpecificOne()
{
//blah
}
}
public class SpecificSomethingTwo : BaseSomething
//and on..
The current example of this is the component based entity system in my game. (I have IComponent, Component, PosComponent, etc).
However, I cannot see a reason to have ISomething. The name may look nicer, but it doesn't seem to have a purpose. I can just return BaseSomething all the time.
Is there a reason to have an interface when you have a single base implementation everything uses? (I can see the use for, say, IComparable or IEnumerable)
EDIT: For a slightly different scenario (yet still related enough to not need a different question), if I assume I have this structure for everything, would there be much difference if I were to use ISomething for parameter types and variables compared to BaseSomething?
I prefer "lazy design" - extract the interface from BaseSomething when you need it. Until then, keep it simple and skip it.
Right now I can think of two reasons for having an interface when there is only one implementation:
There is another mock implementation for unit tests (i.e. there is a second implementation, although not in production code).
The interface and the implementation are defined in different class libraries. E.g. when using the Model-View-Presenter pattern, the view can reside in an .exe project that is dependent on the .dll where the presenter is implemented. Then an IView interface can be put in the .dll and the presenter's reference to the view supplied through dependency injection.
Correct answer to your question would be "It depends".
You can look at it in many different ways and it's all about perspective. When you have a concrete or abstract base class, it means your objects have something in common functionally. And derived objects are inter-related in some way or the other. Interfaces let you confirm to a functional contract only where each object implementing the interface will be responsible for the implementation.
Again, when you program again interfaces, you strictly know the capabilities of the object since it implements the given interface. And you need not worry about how each object functionally implements this.
It'd not be completely wrong, If I say
each of your objects are completely
independent when it comes to
implementing the interface ISomething, given that SpecificSomethingOne and SpecificSomethingTwo do not derive from BaseSomeThing and each implement their own ISomething.
You can refer to this answer on the same matter.
it is not really necessary but it is a better design if you want to extend your program later or you want to implement another Base-Class.
In your case I would not implement the Base-Class. The Interface only is just fine if you dont want to have a default-behaviour. If you want a default-behaviour then just write the Base-Class without an Interface
If your BaseSomething were abstract and you had implementing specific things that provider overloads to abstract methods, the only way to program to them at that point would be to the ISomething interface. However, in the example you showed, there is really no reason for ISomething unless you could have multiple base implementations.

Cast a concrete class instance to an interface that uses generics

Here is my concrete Repository that derives from an abstract base class
public class DepartmentRepository : RepositoryBase<Department>, IDepartmentRepository
public abstract class RepositoryBase<T> : IRepository<T> where T : class, IPersistantBusinessObject
Here is my interfaces
public interface IDepartmentRepository : IRepository<Department>
public interface IRepository<T> where T : IPersistantBusinessObject
public interface IPersistantBusinessObject { ... }
And here is my entities
public class Department : BusinessObjectBase
public abstract class BusinessObjectBase : IPersistantBusinessObject
How do I cast my DepartmentRepository to the generic IRepository?
DepartmentRepository rep = new DepartmentRepository();
(IRepository<IPersistentBusinessObject>)rep; // this doesn't work
Ideas? In case you're wondering, this is an asp.net MVC3 application using the repository pattern. Did I over architect the interfaces? How am I suppose to use a generic repository now?
Thanks.
EDIT:
Here is my IRepository interface. As asked about why I need to cast to IRepository, it is actually only so I can use the "SaveChanges" method, because I want to intercept any exceptions from the database and handled in a common way.
public interface IRepository<T> where T: IPersistantBusinessObject
{
IQueryable<T> Retrieve();
T Retrieve(int id);
IQueryable<T> RetrieveActiveAndInActive();
T RetrieveActiveAndInActive(int id);
void Add(T domainObject);
void SaveChanges();
void Delete(T domainObject);
void Delete(int id)
}
What are you trying to do here? I can't think of a situation in which you would want to cast to IRepository<IPersistentBusinessObject>. What code is dependent on what abstraction?
I would usually expect other code to depend on the abstraction of IDepartmentRepository, and can't really see the use case for IRepository<T> or even IPersistentBusinessObject at all. Again, if you can find a use case for code that depends on that abstraction, then they are valuable; otherwise, YAGNI.
(By the way, this is one reason why test-driven development is valuable. You can figure out which abstractions you need by writing unit tests, and seeing what classes need to be mocked to isolate testing of certain functionality, instead of just vaguely abstracting everything into interfaces because you were told they were better than concrete types. Start with concrete types, and when your tests force you to extract an interface, that's the right time!)
Really though, this is a question of covariance of generic types. It should work if you say
public interface IRepository<out T> where T : IPersistantBusinessObject
You need to cast it to IRepository<Department>.
DepartmentRepository derives from RepositoryBase<Department> which implements IRepository<Department>.
You might want to have a look at co and contravariance...
As Daniel implies, you can't cast it to IRepository, because you've defined the IRepository interface to only exist in conjunction with another type T. So "IRepository" as an interface does not exist.
If you want to be able to use an interface "IRepository" then it needs to be a standalone interface without the type dependence.
Perhaps you need two interfaces, one which implements the basic functionality you want in IRepository, and one which implements the generic methods for type T.
e.g.
<!-- language: lang-c# -->
public interface IRepository
{
SaveChanges()
...
}
public interface IRepositoryFor<T> where T : IPersistantBusinessObject
{
T GetFirst(); // or whatever
...
}

Repository Pattern Standardization of methods

All I am trying to find out the correct definition of the repository pattern.
My original understanding was this (extremely dumbed down)
Separate your Business Objects from your Data Objects
Standardize access methods in data access layer.
I have really seen 2 different implementation, and there are no formal examples online, the ones i have seen are tucked away in books.
Implementation 1 :
public Interface IRepository<T>{
List<T> GetAll();
void Create(T p);
void Update(T p);
}
public interface IProductRepository: IRepository<Product> {
//Extension methods if needed
List<Product> GetProductsByCustomerID();
}
Implementation 2 :
public interface IProductRepository {
List<Product> GetAllProducts();
void CreateProduct(Product p);
void UpdateProduct(Product p);
List<Product> GetProductsByCustomerID();
}
Notice the first is generic Get/Update/GetAll, etc, the second is more of what I would define "DAO" like.
Both share an extraction from your data entities. Which I like, but i can do the same with a simple DAO. However the second piece standardize access operations I see value in, if you implement this enterprise wide people would easily know the set of access methods for your repository.
Am I wrong to assume that the standardization of access to data is an integral piece of this pattern ? If both are correct why would one choose to do implementation 2?
Rhino has a good article on implementation 1, and of course MS has a vague definition and an example of implementation 2 is here.
I second the Fowler quote cited by oded. I want to point out that he said "collection-like" interface. How you implement the collection like interface is certainly up to you, but neither can nor should you try to hide the fact it represents a remote datasource. It therefore differs significantly from an in-memory collection, which does not need to flush changes to a remote data store. The change tracking mechanism of your ORM or your roll-your-own solution determines how transparent this can be made to the caller. Deletes usually need to be marked explicitly, inserts are discoverable (persistence by reachability) and updates sometimes need to be marked explicitly too. Combine this with the complicated dependencies of your aggregate roots and you'll see that's not very collection like.
There is no such thing as "the cannonical repository implementation".
There is a constant battle going on between the advocators of a generic repository base class and those who prefer implementing each repository on its own. While the generic implementation is appealing in simple scenarios, you will very often find it to be a very leaky abstraction. For example some of your aggregates may only be soft-deleted (cistomizable via virtual method overrides) while others may not support a delete operation at all.
Make sure you understand the implications of each approach before deciding which route to take. Greg Young has a good post on the merits of generic repositories.
https://web.archive.org/web/20090204223739/http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx
From Martin Fowler "Patterns of Enterprise Application Architecture", the definition of the Repository Pattern is:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
So, both approaches are correct.
I am a great fan of the generic repository pattern but I think you should strongly consider not directly inheriting from the interface as it can become a very large limitation especially since many times the code for the generic interface will be the same that it could be defined in an abstract base class that you will no longer be able to have more than 1 generic repository inside a class.
I recommend having your IProductRepository implementer access the generic IRepository<Product> through delegation and inject that in through the constructor so you can compose your class of possibly many IRepositories and group them behind a single interface in a way that makes sense.
I wrote a blog on this topic while it specifically references NHibernate this pattern can be applied to any type of repository: Creating a common generic and extensible NHiberate Repository version 2
With the introduction of LINQ in .NET, a generic repository pattern becomes much easier to realize:
public interface IRepository<T> : IQueryable<T>
{
void Add(T item);
void Remove(T item);
}
To qualify as a repository, it merely needs to be able to access data in the underlying store (easily provided by IQueryable) and modify the contained data.
You can provide extensions to the base interface to provide hooks for more entity-specific behaviour (such as wiring into a stored procedure call for a SQL-based repository), but the majority of operations can be completed by the simple interface.
In addition to your generic repository interface (implementation 1) and your variation on the role-specific repository (implementation 2) you can also consider a generic method repository:
public interface IRepository
{
void Save<ENTITY>(ENTITY entity) where ENTITY : DomainEntity;
ENTITY Load<ENTITY>(Guid id) where ENTITY : DomainEntity;
IQueryable<ENTITY> Query<ENTITY>() where ENTITY : DomainEntity;
IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
where ENTITY : DomainEntity;
}
This third version comes from this blogpost by Jimmy Bogard, where he also expresses preference for the generic repository interface.
I usually follow that with a generic repository baseclass which implements this interface; that way, I only have to implement the stuff that is different for each domain entity.
I usually use the generic repository with composition instead of inheritance. That gives me the advantage of a generic implementation, with the control of which methods to expose.
Something like this:
public Interface IRepository<T>{
List<T> GetAll();
void Create(T p);
void Update(T p);
}
public interface IProductRepository {
//Extension methods if needed
List<Product> GetProductsByCustomerID();
List<T> GetAll();
void Create(T p);
//Let assume here you should not be able to update the products
}
public ProductRepository : IProductRepository {
private IRepository _repository;
public ProductRepository(IRepository repository) {
this._repository = repository;
}
List<T> GetAll()
{
_repository.GetAll();
}
void Create(T p)
{
_repository.Create(p);
}
List<Product> GetProductsByCustomerID()
{
//..implementation goes here
}
}
The repository pattern is one of the most used pattern in software development. The are many post that can be marked as answer to your question.
Something that i like to highlight is the fact that a good repository implementation will be improved if you use IoC (Autofac, Windsor, etc...). I have been playing long time ago with some ADO.NET based frameworks (LinqToSql, EF) and NHibernate. You always can have benefits from a generic implementation if you use IoC.
You can define interfaces for your specific repositories and resolve when you really need some specific actions.

Categories

Resources