I was wondering if building a repository on the top LLBLGen (adapter) is a good idea. I don't want to overengineer and reinvent the wheel again. The DataAccessAdapter class could be some kind of a generic repository.It has all the CRUD methods you need.
But on the other side for a larger project it could be good to have a layer between your ORM and service layer.
I'd like to hear your opinions, if your using t开发者_如何学Che repository pattern with LLBLGen,if yes why if no why not.
If you have some implementation, post it please.
The immediate benefit is preventing lock-in to a particular technology, giving you the flexibility to choose the appropriate technology later on.
IMHO, a more important reason is to enforce the Ubiquitous Language. As your application/system evolves, you'll need to query data in multiple ways. The Repository can help you encapsulate complex queries.
With a generic implementation, your consumer code might look like this:
customerRepo = ServiceLocator.Current.Resolve<IRepository<Customer>>();
var matchingCustomers = customerRepo.GetAll().Where(c => <some complex condition here>);
Using a repository, it would look like this:
customerRepo = ServiceLocator.Current.Resolve<ICustomerRepository>();
var matchingCustomers = myRepo.GetCustomersWithOrdersPendingFor(new DateTime(2010, 12, 31));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The second example explictly states the intent of the query, making it easier/quicker to identify in the future.
However (just to complicate matters), you could use Query Specifications to isolate complex query logic, and use then with a generic Repository to get the job done. See this post to see how it's done.
I usually do the following:
- Create a generic repository (i.e. IRepository<TAggregateRoot>)
- Create repositories for each Aggregate Root, implementing IRepository<TAggregateRoot>
- Add query methods as needed to the appropriate repository
- When the repository gets too bloated, refactor the queries into separate Query Specifications
A final note: I once designed an app that worked in both on-line and off-line mode. The easiest solution was to implement two concrete Repositories (using a common interface), and switch between them when the client was connected/disconnected (another example of switching the persistence technology).
We are using the repository with LLBLGen, but with self-servicing. We are using the repository pattern for easing our unit tests. For simple insert/updates, the repository is simply calling the save method of the passed in entity. What we are eventually aiming for is passing domain objects (NOT LLBLGEN entities) back and forth between the repository and the business logic, and only have the ORM (LLBLEN, LINQ-To-SQL, etc) dependencies in the implemented repository.
精彩评论