Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Repository Singleton or Static or None of these?

I have a ASP.NET web site which uses domain driven design and uses repository for its database operations.
I want to know that what is pros and cons of singleton repository and static repository and simple repository class which will new on every access?
further more if anyone can compare and guide me to use which one of them I will be appreciate.

like image 302
JGC Avatar asked Sep 18 '11 17:09

JGC


People also ask

Is Repository a singleton?

I mentioned in passing that I don't like the Repository pattern anymore much, and gotten a lot of responses to that. This is the answering post, and yes, the title was chosen to get a rise out of you. There are actually two separate issues that needs to be handled here.

What is Repository and Singleton design pattern?

First case Singleton can be used in a data repository or data collection where creation of more than one object can be resource wastage. Hence each client is given a reference to a single shared object to operate on. While the second case Singleton can be used in locking mechanisms.

What is Repository in design pattern?

To put it simply, Repository pattern is a kind of container where data access logic is stored. It hides the details of data access logic from business logic. In other words, we allow business logic to access the data object without having knowledge of underlying data access architecture.

What are the examples of singleton?

Example of singleton classes is Runtime class, Action Servlet, Service Locator. Private constructors and factory methods are also an example of the singleton class.


4 Answers

Static and singleton aren't good solution for Repository pattern. What if your application will use 2 or more repositories in the future?

IMO the best solution is to use a Dependency Injection container and inject your IRepository interface in the classes that need it.

I suggest you to read a good book about domain driven design and a good book about dependency injection (like Mark Seeman's Dependency Injection in .NET).


With singletons and static classes your application won't be scalable

You have two singleton repositories:

class Repository<TEntity> {

  static Repository<TEntity> Instance { get { ... /*using sql server*/ } }
}

class Repository2<TEntity> {

  static Repository2<TEntity> Instance { get { ... /*using WCF or XML or any else */ } }
}

The services using them must have a static reference to one of them or both:

class OrderService {

    public void Save(Order order) { Repository<Order>.Instance.Insert(order); }
}

How can you save your order using Repository2, if the repository is statically referenced?

A better solution is using DI:

interface IRepository<TEntity> { ... }

class SqlRepository<TEntity> : IRepository<TEntity> { ....}

class OrderService {
    private readonly IRepository<TEntity> _repo;

    public OrderService(IRepository<TEntity> repo) { _repo = repo; }

    public void Save(Order order) { repo.Insert(order); }
}
like image 99
onof Avatar answered Oct 19 '22 05:10

onof


Don't use static or singleton repositories because of:

  • It affects testablility, you can not mock it when unit testing.

  • It affects extensibility, you can not make more than one concrete implementation and you can not replace behavior without re-compiling.

  • It affects scalability in terms of lifecycle management, insetead depend on dependency injection framework to inject the dependency and manage lifecycle.

  • It affects maintainability, it forces dependency upon concrete implementation instead of abstraction.

Bottom line: DONT use static or singleton repositories

instead create repository interfaces in your domain model project, and implement these interfaces in a concrete data access project, and use dependency injection framework.

like image 34
Mohamed Abed Avatar answered Oct 19 '22 05:10

Mohamed Abed


Two SOLID reasons to not have singleton repository:

  • Consumers of repository will be coupled to repository implementation. This will negatively affect extensibility and testabiliy. This is a DIP violation. Depend on abstractions, not on concretions.

  • Repository implementation will have to violate SRP because it will most likely end up managing ORM session, database connection and potentially transactions. It would also have to make thread safe guarantees because it potentially can be used from multiple threads. Instead, database connection (ORM Session) should be injected into repository implementation so that consuming code can arrange multiple repository calls into transaction.

Possible solution to both problems is Constructor Injection.

like image 43
Dmitry Avatar answered Oct 19 '22 05:10

Dmitry


I personally respectfully disagree with previous answers.

I have developed multiple websites (one with 7 millions page views per month) and never had a single problem with my static repositories.

My static repository implementation is pretty simple and only contains objects providers as properties. A single repository can contain as many providers as you need.

Then, the providers are responsible to manage database connection and transactions. Using TransactionScope, the consumer could manage the transactions or let it to the providers.

Every providers are developed using the singleton pattern.

This way, I can get my objects by simply calling this :

var myObj = MyRepository.MyProvider.GetMyObject(id);

At any time, there is only one repository and one provider of each type in every web pool of my application. Depending on how many users you have at the same time on your site, you could set more than one web pool (but most of the time one is just enough).

I don't see where my repository/providers consumers are coupled with my repository. In fact, the implementations of my providers are totally abstracted from them. Of course, all providers returned by my repository are interfaces and I could easily change the implementation of them at any time and push my new dll on the web server. If I want to create a completely new provider with the same interface, I only have to change it in ONE place: my repository.

This way, no need to add dependency injection or having to create your own ControllerFactory (for MVC procjects).

And you still have the advantage of clean code in your controllers. You will also save a lot of repository creation and destruction every time a page is requested (which normally use reflection in your ControllerFactory).

If you are looking for a scalable solution (if you really need it which most of the time is not really a problem), my way of developing repositories should never be a problem compared to dependency injection.

like image 23
Alwin Avatar answered Oct 19 '22 06:10

Alwin