> I'm just curious if people are using it with RavenDb, for whatever
> reason(s) :)
The app I'm using RavenDB with used NHibernate before and had several
IRepositories. Switching to RavenDB was more or less just changing the
IRepository implementations.
Since then, I've more and more dropped some of the IRepository
implementations. What's still left are repositories with methods more
complex than just running a single Linq/Lucene query or queries that are
used very often in different places of the app and giving them a dedicated
name makes the whole story more readable.
But the typical load/add/save stuff of the repositories is gone and I'm
using the session directly instead.
Tobias
I have one generic implementation for IDocumentStorage and rely on
Autofac to handle the rest of the wiring. So if I need the persistence
service, I injected them thru constructor
public MyObjectConstructor(IDocumentStorage<Blog> blogStorage)
{
blogStorage.Load(xxx);
}
I am working on a web application and majority of the persistence call
are through this IDocumenStorage interface. Anything more complicated
gets its own class.
> I tend to like to move those types of method to an extension method, like
> those:
I haven't considered this yet. It might be a matter of taste, but I
wouldn't feel comfortable with adding application specific code to the
RaveDB session.
Tobias
var store = new DocumentStore { RunInMemory = true; }
And your last paragraph is precisely what is wrong with repository. You can't expose the interesting features from raven/mongo/redis without making a mess of throw not implemented. Repository will only work if you have interchangeable dbs. Raven/mongo/redis/mysql/postgres/sql server/oracle are not interchangeable unless you stick to the most basic functionality.
Statistics, include, async, suggest are features I can point to off the top of my head that won't fit into the typical GetById repository.
Likely there were many other ways to Dry your code. We can explore if you like.
At the end of the day, to be optimal and simple, some code needs to understand the needs of the viewmodel and the capabilities of the storage engine. The controller can serve this role, but so can other classes that the controller invokes. The advantage I see to the latter is that different bits of functionality can be served from different or multiple repositories.
--
You received this message because you are subscribed to the Google Groups "ravendb" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
So my repositories are very thin wrappers. But I'm still very much datastore technology argnostic, which is always a good thing. Especially if your domain outlasts the technology you inject to do infrastructure stuff.
The main thrust of my argument us that being data store agnostic is a mistake and is rarely a good thing.
Its working for you because you're not using any interesting features of the data store.
How agnostic can your repository be if you're using sql server hierarchy ids or raven spatial?
At that point, the generic repository is a lie. If you ever change persistence engines, endless pain ensues.
A better approach, if its actually needed, is to encapsulate chunks of business functionality.
Pretending all db engines are perfectly swappable is not a win. Its extra work, harder to maintain, and won't actually help if you actually switch db engines.
I'm new to raven, so can't really comment on the API too much, but I use the repository pattern and haven't got into too much trouble due to API. But I denormalize a LOT! So most of my raven usage is just loads, ill save the query for where raven should shine and that is searching. After all as someone mentioned its a document store and being such you should try to load over queries as much as possible(ie you need to think more about storing stuff in a document fashion, not a relational fashion).
So my repositories are very thin wrappers. But I'm still very much datastore technology argnostic, which is always a good thing. Especially if your domain outlasts the technology you inject to do infrastructure stuff.
One other point. I try to achieve Load as much as possible as well.
But I wouldn't say that using Query goes against the concept of a document store. In fact, being able to do full text queries to find documents is fundamental.
I would say that setting yourself up to do Loads is a design/optimization point.
And Query != Relational Join.
I agree that setting up your customer facing app so that it can mostly load is a win. Semantic ids are a win here for related data in many situations. Denormalizing data that doesn't or very rarely changes is fine.
Doing lots of denormalizing/patching as an app standard seems counter productive.
A generic repository is a loss.
Indeed
I do use the repository pattern with RavaenDB.At first I dismissed it, but then I came back to ig again, mainly for the following reasons:
1) In our project we have several applications (A Windows Service, an Update Console and the Web Application) thatrequire the same data queries. But the application should not share the same service layer and therefore Iwould have code duplication, if I had to implement these queries several times. And the code would bespread over multiple projects.
2) Our system is multy tenancy capable and actually all data queries must open a session with a specific database.It is recommended that testing for RavenDB is performed with the EmbeddableDocumentStore. ButEmbeddableDocumentStore does not allow to _documentStore.OpenSession("myTenantDatabase") which is what I have touse all the time. Therefore our tests were too complicated and too slow. Whereas, a repository is very easy to mock.
3) In our project not all developers know RavenDB equally good. Therefore, the data access code is encapsulated in aLibrary and the less specialized developers work only with the repository interfaces. The implementation is doneby a RavenDB connoisseur.
The use of repositories is not free. We have the following disadvantages with the use of repositories:1) Session Handling: To avoid problems with sessions we use for each action a new session.This comes with some minor performance losses
2) Projections: We must implement all projections explicitly as classes and can not use anonymous Types.
3) Even we avoid code duplication we write more code because the overhead of the additional library.The decision was not easy for me, but the benefits outweigh.In another project, it may again be quite different.A general statement can not be made in my opinion as it always depends on the current problem at handand the advantages and disadvantages should be compared.
I use natural keys or comb guids where each are required.
Eg guid for persisting model docs. A natural key might be an emailaddress for a usersbyemailaddress doc.
And I only use this for read models (reads). My write side is an event stream only (see cqrs with eventsourcing).
Btw: A session is always (well with datastore technology ive used) required so my repo's have a generic context/session that any layer manages(opens and closes).
public class GetLoyalCustomersCommand : IDatabaseCommand<GetLoyalCustomersCommand.Result>{public class Result{// result properties go here}// command/query properties go hereGetLoyalCustomersCommand.Result IDatabaseCommand.Run(IDocumentSession db){// magic goes herereturn result;}}
var result = Database.Execute(new GetLoyalCustomersCommand{SomeInput = "weee",SomeNumber = 4,});
Hi folks,
are any/many people using the Repository Pattern with RavenDb? As I
start learning RavenDb, my first reaction was to do this. And it works
fine. But I keep feeling that my Repository Pattern wrapper is just a
waste. Now -> i'm trying to be vary careful here because i don't want
to start a debate about the use of patterns and interfaces to remove
dependencies, help with mocking / testing / tight coupling, etc. ~~
This is not what I'm asking about ~~
I'm just curious if people are using it with RavenDb, for whatever
reason(s) :)
If you are, can u say why?
If not, can u also say why :)
I'm really really curious.
-Justin-