502

The single best reason to not use the repository pattern with Entity Framework? Entity Framework already implements a repository pattern. DbContext is your UoW (Unit of Work) and each DbSet is the repository. Implementing another layer on top of this is not only redundant, but makes maintenance harder. People follow patterns without realizing the purpose of ...


8

The Entity Framework DbContext is a unit of work, and its DbSet<T> properties are repositories. That's not to say that you should never roll your own layer on top of them, but you're correct in asserting that the db context, in the way you're using it, precludes the main goal of a unit of work. Your situation is quite unique in that you manually ...


6

A very good reason to use the repository pattern is to allow the separation of your business logic and/or your UI from System.Data.Entity. There are numerous advantages to this, including real benefits in unit testing by allowing he use of Fakes or Mocks.


6

In general a unit of work corresponds with a database transaction. So from that perspective: BEGIN TRANSACTION -- do stuff COMMIT TRANSACTION Databases are very advanced with how they handle this. Any data you read after the BEGIN TRANSACTION statement is "locked" to any other thread (note that you can override this behavior in your SELECT statement ...


6

This is a common problem in testing. You have class A that uses class B that uses class C. So how do you test class B? You must be able to mock class C and pass it to class B before you can test B. In your case, we're talking about UnitOfWork depending on ICustomerRepository. The trick is this: if UnitOfWork is responsible for instantiating an ...


5

The immediate problem I see here that it becomes hard to unit test the "UnitOfWork" with mock repositories. What if the line repoItem = new Repository<TEntity, object>(Context); needs to be replaced by ... new MockRepository for a meaningful test? So in case UnitOfWork just needs one or two, maybe 3 repos, you could try to inject them in the ...


5

The core argument for using repositories is to prevent leaking EF dependent code into your domain. That argument is not wrong, it just comes with a steep cost, i.e. a high-complexity uow/repo layer, which is now being regarded (by some, at least) as too high a price to pay for what it gives back. By not using that uow/repo layer, you do actually let your ...


4

If you follow the pattern described in the article, then you would only need to change MockRepository or MockUnitOfWork if the respective interface (IRepository and IUnitOfWork) changes. The idea behind this is that you can unit-test all the other parts of your application without needing access to a real database (and without the trouble that data ...


4

Your question is a little odd, sort of like asking why you need the unit of work pattern when you could just use objects. Monads are more fundamental than your question implies. You can use a monad as part of the implementation of the unit of work pattern, but that's not a sufficient description of the solution. You would also need to describe which monad ...


4

The Unit-Of-Work pattern makes sense when you have a complex use case with several objects involved, often objects which map to different master-detail tables. As part of the use case, you want to pull all the required objects out of the database let the user edit these objects (his local copy), until they are satisfied with the result. "Edit" here may ...


3

There is no "one size fits all" answer to where you should put the boundaries of your SUT. The optimal size of a SUT for unit-testing depends on a lot of factors, including The language and toolchain you are working with (how many errors can be detected by static analysis/compiling the code) The complexity of the product you are making How familiar the ...


3

Ideally things would vary according to the rule of common sense. Martin Fowler talks about a unit as a class (plus related classes in some cases) and IMHO a unit should be a useful lump of code, this may be a single method where a method is quite complex, or a whole class as classes are the means of dividing a system into manageable components. A single ...


3

Your repositories need to depend on the DbContext and not vice versa. Also, you don't have to implement Unit of Work since the DbContext already implements it. You could do it like this: public interface IRepository<T> { T ReadOne(object key); // so on, so forth... } public class Repository<T> : IRepository<T> where T : class, ...


3

Yes, there are many problems with this approach. First, The EF DBContext is not thread safe. If you make it static, then multiple users hitting this DbContext at the same time can cause data corruption, particularly if you're saving any items to the database. Even if it's read-only, you still have to deal with the fact that objects get inserted into the ...


3

After trying out repository pattern on small project I strongly advise not to use it; not because it complicates your system, and not because mocking data is nightmare, but because your testing becomes useless!! Mocking data allows you add details without headers, add records that violate database constraints, and remove entities that the database would ...


3

Both the saga and unit of work patterns intend to ensure consistency of related operations, but at different levels: The saga pattern aims at ensuring consistency across independent services and without using a two phase commit. The unit of work pattern aims at ensuring consistency (usually within a system) by making sure that the object states and the ...


2

If you stop worrying about your data and start thinking about your domain model it will become much more clear. I now see you are stuck with unit of work, repositories, data operations, layers and adapters but you forget about your business. What I would suggest to do is to have proper rich domain model designed and have a service layer that will play ...


2

I have went through this loop in the last few years, Unit Of Work, wrapping of repo's all calling Entity Framework. You end up with a lot of pointless repository classes (with associated interface), probably wrapping a generic base repo class with a Unit Of Work on top that has lots of properties which expose the repo's. And yes, you are correct, Entity ...


2

DBContext only provides you with a UoW pattern if you code up all the changes in one go yourself, which is pretty much no different to writing a single query in SQL yourself. You should use the UoW pattern if performance is your concern - writing a single hit to the DB is better than writing 1 hit per change. However, most people use an ORM for RAD tooling ...


2

In the desktop application I am currently working at we solved similar problems by introducing an event mechanism, centered around a global "Event Manager". We have got a handful of "main business objects" (~10 different types), and whenever one dialog changes a business object, it raises a "change" event, including the type and the ID of the related object (...


2

A fairly simple extension of the Unit of Work pattern would be do create an interface (call it ITransactionItem, perhaps) that contains commit and rollback methods. You could then make each of your unit of work objects implement that, along with any object that performs related functions, like your file operation. A new, top level unit of work would then ...


2

You mention "EF auto generated classes", which suggest you're using a DB-first approach. But you mentioned in the comments that you're open to anything, so I want to suggest switching to a Code First approach. Robert Harvey's answer isn't wrong, I simply want to offer another viable solution to the problem. Note: I don't know much about EF Core ...


2

I would first determine if I am doing dependency injection or not. Your first option is using dependency injection properly, the second option is not using it correctly. Although, just because you are using a dependency does not mean you have to expose it outside your class. For example, with constructor injection you have in your implementation class, ...


1

According to Microsoft, DBContext.SaveChanges already implements a Unit of Work. It does this by wrapping the entire operation in a database transaction. Further Reading Entity Framework Working with Transactions


1

The author is using a LINQ to SQL DataContext which is not that simple to mock. There are ways to mock it but you can simply go around that and create a fake implementation of a Repository and UnitOfWork to use in your tests. If you go the extra mile and create a viable mock for a DataContext then you shouldn't create mocks for your Repository and UnitOfWork....


1

I don't know if it is good practice to mock database context? Will it be enough if I mock IRepository and only test UnitOfWork? Always think about what you actually need to test. Even Uncle Bob admits he doesn't test his GUI. He also insists you move all logic out of the GUI. It's the same with the DB. If you can move all the interesting logic away from ...


1

Should I unit test Repository on it's own? I don't think there's much point. A Repository is supposed to act as a layer of abstraction between your business logic and the database, so by the time you mock the database for testing purposes, all that's left to test is the Repository's API endpoints (a test that I would regard as "uninteresting", and already ...


1

These are two different patterns with completely different purpose: The service layer is about application boundary and API (visibility & granularity of operations); The unit of work is about transaction management and concurrency. Of course the service layer could group operations that are exposed. For example save a PurchaseOrder together with ...


1

Your approach is fine so far. The "Unit-of-Work" class should get the responsibility to keep track of the changes to your "settings entity" for one "transaction" (it could do this, for example, by keeping a list of commands or changed objects, if there would be more than one object involved), and the abstract repository should provide an abstraction for the ...


1

The major problem I see is that your EnvelopeService class is not threadsafe. Imagine two threads using a single instance of EnvelopeService. Thread 1 calls GetEnvelope which creates a UnitOfWork. At the same time Thread 2 calls SaveEnvelope which creates a second UnitOfWork. Whether those two operations are carried out using the appropriate UnitOfWork is ...


Only top voted, non community-wiki answers of a minimum length are eligible