1

I'm trying to build a repository layer for an application which interacts with 3 databases, all MSSQL. I made the repository structure is based on Dapper and Unit Of Work Pattern and looks like below: Generic Repo design

Is this a good design? or what could be a better design for this?

I do not want to pass the connection instance from business, as it's not the job of a business layer; and should be of the data layer itself. Currently, am trying to manage the connection within the UnitOfWork class with the connection name and would like to change it.

EDIT: The design is not possible as it has multiple class inheritance, which is not possible in c#. Are there any alternate solutions?

Community
  • 1
  • 1
Kay
  • 702
  • 7
  • 16
  • Do you have to use repositories and inheritance? – Callum Linington Aug 14 '15 at 12:09
  • I think the best thing you could do is put a wrapper around dapper so that you can make it more unit testable. Then build out your solution refactoring as you need. I wouldn't necessarily jump into UOW and Repos until you absolutely need to. Have a look at MediatR for breaking down requests into small unit testable pieces of code. (removes the need for services, UOW and Repos somewhat) – Callum Linington Aug 14 '15 at 12:13
  • Mediatr command handlers _are_ the services. Anyway what the OP has here is a real mess. – MikeSW Aug 15 '15 at 15:33

1 Answers1

1

There's very little info to work with here, but I'll try. It doesn't matter how many db you're using or their type. The repository with UoW is an anti pattern which becomes even worse with multiple dbs.

A repository should work with whole concepts (aggregates). I'm going the DDD route because is the easiest way to model things in an app. A repository will take care of one aggregate type. Its implementation will use dapper to work with the db.

If you need to modify multiple aggregates in one operation, first do make sure the business process is modeled properly (usually it's not). The business process itself is the UoW but this implies using Domain Events and a durable service bus (to be server crash resilient). And every message handler should be idempotent.

A repository should never know about other repos and the inheritance part is mostly a dubious design. The UoW inside the repo which enables the persistence of the whole aggregate regardless of how many objects it's made from, is the db transaction. Don't complicate your life with distributed transactions, keep a transaction per db.

That being said, it's obvious that a proper architecture (it has very little to do with the repository pattern, even less with dapper) needs someone with a lot of experience if you want a maintainable codebase. If you're a junior, ask a senior or take some time to learn DDD modelling properly. It's very easy to come up with 'solutions' that seem simple enough but are an unmaintainable mess.

MikeSW
  • 16,140
  • 3
  • 39
  • 53
  • Thanks @MikeSW, I'll give a try. As of now, the models are separated based on the functionality. I'm trying to manage transactions with TransactionScope at business layer. There wasn't much time for developing this, so had to go with a work around - passing the correct connection name from the individual repository classes, and the generic repo will pass it to the UoW to get the correct connection. Which did the job for now. I'm aware that it isn't a better design; but due to time constraints, had to go ahead with it. :) – Kay Aug 19 '15 at 06:17