Single repository with generic methods ... bad idea? - nhibernate

I'm currently trying out a few different ways of implementing repositories in the project I'm working on, and currently have a single repository with generic methods on it something like this:
public interface IRepository
{
T GetSingle<T>(IQueryBase<T> query) where T : BaseEntity;
IQueryable<T> GetList<T>(IQueryBase<T> query) where T : BaseEntity;
T Get<T>(int id) where T : BaseEntity;
int Save<T>(T entity) where T : BaseEntity;
void DeleteSingle<T>(IQueryBase<T> query) where T : BaseEntity;
void DeleteList<T>(IQueryBase<T> query) where T : BaseEntity;
}
That way I can just inject a single repository into a class and use it to get whatever I need.
(by the way, I'm using Fluent NHibernate as my ORM, with a session-per-web-request pattern, and injecting my repository using Structuremap)
This seems to work for me - the methods I've defined on this repository do everything I need. But in all my web searching, I haven't found other people using this approach, which makes me think I'm missing something ... Is this going to cause me problems as I grow my application?
I read a lot of people talking about having a repository per root entity - but if I identify root entities with some interface and restrict the generic methods to only allow classes implementing that interface, then aren't I achieving the same thing?
thanks in advance for any offerings.

I'm currently using a mix of both generic repositories (IRepository<T>) and custom (ICustomRepository). I do not expose IQueryable or IQueryOver from my repositories though.
Also I am only using my repositories as a query interface. I do all of my saving, updating, deleting through the Session (unit of work) object that I'm injecting into my repository. This allows me to do transactions across different repositories.
I've found that I definitely cannot do everything from a generic repository but they are definitely useful in a number of cases.
To answer your question though I do not think it's a bad idea to have a single generic repository if you can get by with it. In my implementation this would not work but if it works for you then that's great. I think it comes down to what works best for you. I don't think you will ever find a solution out there that works perfectly for your situation. I've found hybrid solutions work best for me.

I've done something similar in my projects. One drawback is that you'll have to be careful you don't create a select n+1 bug. I got around it by passing a separate list of properties to eagerly fetch.
The main argument you'll hear against wrapping your ORM like this is that it's a leaky abstraction. You'll still have to code around some the "gotchas" like select n+1 and you don't get to take full advantage of things like NH's caching support (at least not without extra code).
Here's a good thread on the pros and cons of this approach on Ayende's blog. He's more or less opposed to the pattern, but there are a few counter arguments too.

I've implemented such kind of repository for NHibernate. You can see example here.
In that implementation you are able to do eager loading and fetching. The pitfall is that with NH you will often need to be able to use QueryOver or Criteria API to access data (unfortunately LINQ provider is still far from being perfect). And with such an abstraction it could be a problem leading to leaky abstraction.

I have actually moved away from repository pattern and creating a unit of work interfaces - I find it limiting.
Unless you anticipate a change in the datastore i.e. going from DB to textfile or XML - which has never been the case for me, you are best off using ISession. You are trying to abstract your data access and this is exactly what NHibernate does. Using repository limits really cool features like Fetch(), FetchMany() futures etc. ISession is your unit of work.
Embrace NHibernate and use the ISession directly!

I've used this approach successfully on a few projects. It gets burdensome passing in many IRepository<T> to my Service layers for each BaseEntity, but it works. One thing I would change is put the where T : on the interface rather than the methods
public interface IRepository<T> where T : BaseEntity

Related

Registering multiple DbContext Instances on startup for use in Generic Repository

I'm trying to create a Generic repository which accepts 2 generic types e.g.
public class EfRepository<T, TS> : IAsyncRepository<T,TS> where T : BaseEntity
where TS : DbContext
{
..........
}
and in my startup.cs I have the usual mapping:
services.AddScoped<DbContext, ConfigDbContext>();
How can I now add another mapping to DbContext? I have tried adding another mapping between DbContext and another Context i created but It only ever uses the first mapping.
I have multiple databases I need to consume and would ideally like to have a DbContext for each one but i can't see a way of having multiple DI mappings.
In my EfRepository class the following code exceptions when I add an extra DbContext to my code and use it:
protected readonly DbContext _dbContext;
public EfRepository(DbContext dbContext)
{
this._dbContext = (TS)dbContext;
}
The exception is Unable to Convert from Type1 to Type2 and I know this is because the DbContext is bound to Type1 in my startup.cs.
How can I (if possible) use multiple DbContext's in a generic fashion?
That's not how you register DbContext, which is the source of your problem. The correct method is:
services.AddDbContext<ConfigDbContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("Foo")));
Done correctly, adding another is exactly the same:
services.AddDbContext<SomeOtherContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("OtherConnectionString")));
Then, which one gets pulled depends on which one you inject, which yes, does mean that you need to specify the actual type you want to inject, not DbContext generically. However, that can be done only one the derived class. In other words, you can keep the code you have (though you should not cast the context) and simply do:
public class FooRepository : EFRepository<Foo, ConfigDbContext>
{
public FooRepository(ConfigDbContext context)
: base(context) {}
}
You can leave it upcast to DbContext, as you don't need the actual type to do EF things. To get at the DbSets, you can use the generic Set<T>:
var foos = _dbContext.Set<Foo>();
And now, with all that said, throw it all out. It's completely unacceptable to use the repository pattern with an ORM like EF. EF already implements the repository and unit of work patterns. The DbContext is your unit of work, and each DbSet is a repository. Adding an extra layer on top of that does nothing but add maintenance concerns and extra entropy to your code, and frankly, creating a repository/unit of work that plays nice with EF, is so trying as to be impossible, so more often than not, you're just going to hamstring EF, making it less efficient and harder to use.
Using an ORM like EF is choosing to use a third-party DAL. That is all. There's no need to create your own DAL at that point, because you've outsourced it. I'm not sure why so many people get hung up on this. When was the last time you created your own routing framework or your own templated view preprocessor. Never. You just third party libraries for that (the framework), so why is it a problem to use a third party library for your DAL as well?
Then, you make ask well what about abstracting the EF dependency. Well, first, if you're thinking you might switch ORMs some day down the road, you won't. It just never happens. You'll sooner rewrite the whole app from the ground up. Second, the repository pattern doesn't even achieve this. You still have an EF dependency that bubbles all the way up to the front-line app. There's no way around that.
For true abstraction, you can use something like microservices architecture. Other than that, just embrace the dependency or don't use it at all, and really create your own DAL.

Repository Pattern - Structuring repositories

I am trying to use repositories in my MVC program designs and I have run up against a problem on how to best structure them.
as an example, say I have an object USers and I have a UserRepository which has functions like getUser(int id), saveUser(Dal.User model) etc...
So If in my controller I have EditUser and I want to display a view that will have a user details input form. so I can do something like this:
User user = _userRepository.getUserDetails(userId);
The benefit being that my controller just deals with processing HTTP requests, and business logic is moved to repositories, making testing etc easier
So, say I want to display a drop down list of possible roles this user could have in my system, ie client, admin, staff etc
is it ok to have a function in the _userRepository called getPossibleUserRoles() or should I have a seperate _roleRepository with a function getRoles() ?
IS it a bad idea to inject a repository for every entity you encounter into your controller? or is it a bad idea to mix entities inside your repositories, making them cluttered.
I realise I have presented a very simplistic scenario, but obviously as systems grow in complexity you are potentially talking of 10s of repositories needing to be instantiated in a controller for every page call. and also possibly instantiating repositories that are not being used in current controller methods simply to have them available to other controller methods.
Any advice on how best to structure a project using repositories appreciated
is it ok to have a function in the _userRepository called
getPossibleUserRoles() or should I have a seperate _roleRepository
with a function getRoles() ?
Let's say you have some controllers call:
_userRepository.getUserDetails(userId);
but they never call:
_userRepository.getPossibleUserRoles(userId);
Then you are forcing your controllers to depend on methods they do not use.
Sot it's not just ok, you should split this.
But if getUserDetails and getPossibleUserRoles are chosive (sharing same entity, sharing same business logic etc..).
You can split this without changing implemantation of userrepository beside of creating new class for Roles.
public class UserRepsitory : IUserRoles, IUserRepository
{
}
I realise I have presented a very simplistic scenario, but obviously
as systems grow in complexity you are potentially talking of 10s of
repositories needing to be instantiated in a controller
If a constructor gets too many parameters, there is high posibility SRP violation. Mark Seemann shows how to solve this problem in here.
In a short way: While you are creating a behaviour, if you use always 2 or more than repositories together. Then, these repositories are very close. So you can create a service and orchestrate them in this service. After that, you can use this service as a paremeter beside of using 2 or more repositories in your controller constructor.
is it ok to have a function in the _userRepository called getPossibleUserRoles() or should I have a seperate _roleRepository with a function getRoles() ?
Both solutions are acceptable but consider how you're going to control the proliferation of repositories and methods on those repositories. IMHO, the typical repository usage scenario tends to end-up with too many repositories with too many methods on each. DDD advocates a repository per aggregate root. This is a good rule of thumb... if you're following DDD principles.
IS it a bad idea to inject a repository for every entity you encounter into your controller? or is it a bad idea to mix entities inside your repositories, making them cluttered.
Inject volatile dependencies, so yes, inject a repository for every entity your controller needs. However, once you start injecting more than four dependencies, chances are you've missed an abstraction somewhere in your design. Some solve this problem with RepositoryFactory but this, arguably, introduces the problem of opaque dependencies and, IMHO, fails to convey the class's real dependencies, reducing its usability and self-document-ability.
Take a look at using query objects rather than repositories (https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/, etc.) and take a look at using orchestration/mediation (http://codeopinion.com/thin-controllers-cqrs-mediatr/) in your controllers. I think you'll find a better design emerges that will help you with your design issues.

NHibernate and repositories design pattern

I've been working with NHibernate for quite a while and have come to realize that my architecture might be a bit...dated. This is for an NHibernate library that is living behind several apps that are related to each other.
First off, I have a DomainEntity base class with an ID and an EntityID (which is a guid that I use when I expose an item to the web or through an API, instead of the internal integer id - I think I had a reason for it at one point, but I'm not sure it's really valid now). I have a Repository base class where T inherits from DomainEntity that provides a set of generalized search methods. The inheritors of DomainEntity may also implement several interfaces that track things like created date, created by, etc., that are largely a log for the most recent changes to the object. I'm not fond of using a repository pattern for this, but it wraps the logic of setting those values when an object is saved (provided that object is saved through the repository and not saved as part of saving something else).
I would like to rid myself of the repositories. They don't make me happy and really seem like clutter these days, especially now that I'm not querying with hql and now that I can use extension methods on the Session object. But how do I hook up this sort of functionality cleanly? Let's assume for the purposes of discussion that I have something like structuremap set up and capable of returning an object that exposes context information (current user and the like), what would be a good flexible way of providing this functionality outside of the repository structure? Bonus points if this can be hooked up along with a convention-based mapping setup (I'm looking into replacing the XML files as well).
If you dislike the fact that repositories can become bloated over time then you may want to use something like Query Objects.
The basic idea is that you break down a single query into an individual object that you can then apply it to the database.
Some example implementation links here.

Entity Framework - implementing IDbSet

I would like to implement IdbSet to provide my DbContext a custom implementation that will essentially serve to filter my data for the currently logged in user (I am working on a multi-tenant application). The general idea I am going with is very similar to this post: Can a DbContext enforce a filter policy?
However, it is not clear to me how to make DbContext "know" about how to use my own class that implements IDbSet. I am having a tough time finding documentation on this. Any pointers would be helpful!
TIA,
-jle
I'm almost sure that you cannot create your own implementation of IDbSet and pass it to entity framework. Such implementation will lose all stuff related to EF which is internally implemented in DbSet itself - by internally I really mean that there is no public API to replace it. IDbSet interface is provided not because it is supposed to create your own sets but because it allows mocking sets when unit testing application. The only way you can extend functionality is either:
Inheriting DbSet but I'm afraid that it will not help you as well because methods / properties will not be marked as virtual.
Creating custom IDbSet implementation which will wrap DbSet. This looks like the best chance but you can still find that DbContext doesn't like your new implementation. I gave this very quick try but I was not successful. My implementation worked for persisting but not for querying.

Dependency injection with NHibernate objects

I am wondering how to tell NHibernate to resolve dependencies on my POCO domain objects.
I figured out that methods like CalculateOrderTax should be in the Domain object because they encode domain specific business rules. But once I have two of those I am violating SRP.
It would be no problem to extract those methods to Strategy classes, but I wonder how to make NHibernate load those.
It doesn't seem like a good solution to loop through a list of objects in the repository to do get/set based Dependecy injection before handing the object off to the higher layers.
I am also using Castle Windsor for my Depency injection right now.
I've been using interceptors for similar tasks:
An interceptor that modifies loaded entities:
public class MyInterceptor : EmptyInterceptor
{
public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
return InjectDependencies(entity as MyEntity);
}
}
Associate it with a session:
nhSessionFactory.OpenSession(myInterceptor);
I've also read somewhere that there would be better support for custom constructor injection in the upcoming 2.1 release but I can't seem to find the reference right now.
As no-one seems to be able to answer your question at the moment I thought I'd suggest restructuring your code to remove the need for the Order to calculate it's own tax.
You could delegate it to a OrderTaxService which takes an Order object and returns an OrderValue object or something along those lines.
This will keep the logic in your domain but remove the need to attach it to your Order objects.
I agree with Garry that you should remove service dependencies from your domain objects as much as possible. Sometimes it makes sense, such as encryption/decryption. In that case you can hide it in the infrastructure using interception or IUserType. I think the latter is favorable when you can use it. This article shows in detail how to do it. I am doing this and it works quite fine.