I'm gonna to use repository and UnitOfwork in my data access layer to do this take a look at one contact aggregateroot
public interface IAggregateRoot
{
}
this is my Generic repository interface :
public interface IRepository<T>
{
IEnumerable<T> GetAll();
T FindBy(params Object[] keyValues);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
}
and my POCO Contact class in Model
public class Contact :IAggregateRoot
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationTime { get; set; }
}
and this my IContactRepository that inherit from IRepository and also maybe has it is own method
public interface IContactRepository : IRepository<Contact>
{
}
Now I have done in IUitOfWork and UnitOfwork like this
public interface IUnitOfWork
{
IRepository<Contact> ContactRepository { get; }
}
public class UnitOfWork : IUnitOfWork
{
private readonly StatosContext _statosContext = new StatosContext();
private IRepository<Contact> _contactUsRepository;
public IRepository<Contact> ContactRepository
{
get { return _contactUsRepository ?? (_contactUsRepository = new Repository<Contact>(_statosContext)); }
}
}
also about my Repository
public class Repository<T> : IRepository<T> where T : class, IAggregateRoot
{
//implementing methods
}
I can do all CRUD operation with accessing Repositories with UnitOfwork in Service , example :
_unitOfWork.ContactRepository.Add(contact);
_unitOfWork.SaveChanges();
but I want to do like this
_
ContactRepository.Add(contact);
_unitOfWork.SaveChanges();
(get CRUD and generic method via _ContactRepository No by _unitOfWork.ContactRepository)
Because I want to get ContactRepository method to some specific queries ,
anybody help please ??
It's not a direct answer to your question, but it might simplify things a little bit and reduce duplication.
When you use e.g. EntityFramework Power Tools to reverse-engineer Code First (or just use Code First in general), you end up with the DbContext class that serves as a UoW and repository in one, e.g.:
public partial class YourDbContext : DbContext
{
public DbSet<Contact> Contacts {get; set;}
}
Now, if you want things to be testable, there's an easy way: introduce a very thin interface:
public interface IDbContext
{
IDbSet<T> EntitySet<T>() where T : class;
int SaveChanges();
//you can reveal more methods from the original DbContext, like `GetValidationErrors` method or whatever you really need.
}
then make another file with second part of the partial class:
public partial class YourDbContext : IDbContext
{
public IDbSet<T> EntitySet<T>() where T : class
{
return Set<T>();
}
}
Ta-da! Now you can inject IDbContext with YourDbContext backing it up:
//context is an injected IDbContext:
var contact = context.EntitySet<Contact>().Single(x => x.Id == 2);
contact.Name = "Updated name";
context.EntitySet<Contact>().Add(new Contact { Name = "Brand new" });
context.SaveChanges();
Now if you want to have control over the disposal of the context, then you'd have to write your own (gasp) IDbContextFactory (generic or not, depending what you need) and inject that factory instead.
No need to write your own Find, Add or Update methods now, DbContext will handle that appropriately, it's easier to introduce explicit transactions and everything is nicely hidden behind interfaces (IDbContext, IDbSet).
By the way, the IDbContextFactory would be an equivalent to NHibernate's ISessionFactory and IDbContext - ISession. I wish EF had this out of the box, too.
I agree with the Doctor, DbContext is already a UnitOfWork, and adding another UoW abstraction on top of it is typically redundant, unless you think it's highly likely you might switch database technologies in the future.
I don't agree, however, with treating DbSet's as repositories, since this tightly couples your queries to the methods that use them. If you need to change a query, you have to do it everywhere you use it.
I prefer to either use a stand-alone repository (or service interface, they serve similar functions) or to use more of a CQRS system for Command/Query Seperation, an use query objects.
Inside the UnitOfWork class you need to implement DBContext or ObjectContext.
UnitOfWork segregates all transactions regardless of the system. EF is only for DB connection. Even if your system is only using DB still it is better to keep a separate UnitOfWork class for future expansions.
And inside the unit of work Commit(), you can call the internally implemented DBContext.SaveChanges().
This DBcontext will be accessible to all repositories declared inside unitofwork. So repositories add or delete from DBcontext and unitOfwork commits it.
When you have scenarios spanning different storages eg: Cloud Blobs, table storage etc. You could implement them inside UnitofWork just like you implemented a EF context. And some repositories can access Table Storage and some EF context.
Tip: Implementing ObjectContext instead of DBContext gives you an edge in caching scenarios. And you have more options in extending your framework.
Related
Hello I use entity framework with a unit of work pattern and I would like to know if in my application layer I should work directly with entities generated by entity framework or recreate POCO objects in my application layer and map my POCO?
Because I would like my application layer not to make any reference to my entities, I would like for example to create another project in my solution that could map my entities to my poco in my application but I don't know if this is a good practice and especially I don't know how to do it
Thank you in advance!
In my UnitOfWork I have used a generic repository pattern that uses the models generated by the EF directly. The IRepository<T> interface looks a bit like this:
public interface IRepository<T> where T : class
{
void Add(T entity);
T GetById(long Id);
//etc - all the stuff you probably have
}
I have implementation of the IRepository called Repository
public Repository<T> : IRepository<T>
{
public readonly Infomaster _dbContext;
public Repository(Infomaster dbContext)
{
_dbContext = dbContext;
}
public void Add(T entity)
{
_dbContext.Set<T>.Add(t);
}
}
The use of the set and the type allows me to access the dataset (dbSet) of that particular type which allows me to create a generic pattern. You can use specific classes but it's a lot more work.
This means in my UnitOfWork, I only need to do the following:
public class UnitOfWork : IUnitOfWork
{
//Db context
Infomaster _dbContext;
//User is a model from my EF
public IRepository<User> UserRepository { get; private set; }
public UnitOfWork()
{
_dbContext = new Infomaster();
UserRepository = new Repository<User>(_dbContext);
}
public int Commit()
{
return _dbContext.Save();
}
}
I find that is the best way and requires the use of the model classes, I am using a code first database but I have done with database first.
(from iPhone - can and will update from laptop)
I have no choice in creating a data first Entity Framework implementation. I want to extend the generated class to include a generic base class that I can call all the basic functions on. (I know how to update the t4 templates)
Update (add if not currently in DB), GetAll, Select (based on parameters) and Delete functions. I have found a few things that I think may work but they do not have fully qualified namespaces and I can't figure out where the information is stored.
Creating base class for Entities in Entity Framework - is one such which is basically a duplicate of my question but the answers are not complete.
What would be an example of this base class WITH the fully qualified namespace?
You can still use Code First even though you have a database. You can generate your model. Depends what you need, please see 2 different ways to approach the problem.
Generic repository
public abstract class BaseRepository<TEntity> where TEntity : class
{
protected DbContext context;
protected BaseRepository(MyDbContext context)
{
this.context = context;
}
public List<TEntity> GetAll()
{
// Set<TEntity> provides you an access to entity DbSet
// Just like if you call context.Users or context.[AnyTableName]
return context.Set<TEntity>().ToList();
}
}
Next you want to implement entity-specific repositories:
public class UserRepository : BaseRepository<User>
{
public UserRepository(MyDbContext context) : base(context)
{
}
}
Simple usage example:
using (var context = new MyDbContext())
{
var userRepository = new UserRepository(context);
var users = userRepository.GetAll();
}
Just put your generic methods in context
public class MyContext : DbContext
{
public DbSet<User> Users { get; set; }
// ... more DbSets
public List<TEntity> GetAll<TEntity>() where TEntity : class
{
return Set<TEntity>().ToList();
}
// For entities that implement INamedEntity interface
// with property Name.
public TNamedEntity FindByName<TNamedEntity>(string name)
where TNamedEntity : INamedEntity, class
{
return Set<TNamedEntity>()
.FirstOrDefault(entity => entity.Name == name);
}
}
I use nuget package EntityFramework. DbContext and DbSet comes from System.Data.Entity namespace.
Hope it's enough for you to get started and implement all the methods that you need.
I'm currently building an ASP.NET MVC 5 application using Unity and Entity Framework.
Here is my architecture (the solution contains multiple projects) :
Bootstrapper : project that contains the link between my interfaces and class for the repositories and the services
Data : mapping between my models and the database objects. This project contains the repositories as well.
Domain : this one contains the application constants + the interfaces of my repositories and services
Models : contains the models used in the application
Services : contains all the class Services
Web : the actual application with the views, controllers, view models, ...
Here is my issue: in multiple services I have the same methods (Get an item, check if it exists, ...) and these methods are exactly the same in every services except that they don't use the same repository and the same model.
Example :
public IQueryable<Car> Search(string search)
{
#region Sanitize parameters + Contracts
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(search), Resources.Resources.SearchRequired);
search = StringHelper.SafePlainText(search);
Contract.Assume(search.Length <= 100 && search.Length > 1);
#endregion
return _carRepository.Search(StringHelper.SafePlainText(search));
}
I want to "extract" these methods so I don't have to recreate the same code over and over.
First, I thought about create an abstract class that my service inherit from but I couldn't figure out how to pass the right repository to the mother class.
This is what I tried :
public abstract class Service<T>
{
public object Repository { get; set; }
protected Service(object repository)
{
Repository = repository;
}
public IQueryable<T> Search(string search)
{
#region Sanitize parameters + Contracts
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(search), Resources.Resources.SearchRequired);
search = StringHelper.SafePlainText(search);
Contract.Assume(search.Length <= 100 && search.Length > 1);
#endregion
return Repository.Search(StringHelper.SafePlainText(search));
}
}
But this, of course, doesn't work.
So I'm asking you guys if you have an idea to how I can manage to make this work, if this is possible at least.
Thank you in advance and excuse me for the poor language, I'm not an English native speaker.
Thibault.ce
First, you can inherits all your entity framework objects from a base class (optional) : http://fairwaytech.com/2013/09/using-a-common-base-class-across-entity-framework-database-first-entities/
Then, you can create a generic class "BaseRepository" which is based on the base class you created (or just "class"). This class will contains all generic methods. In this class, you can access the table corresponding to the base object using the entityframework method "Set()", which returns the DbSet of the typed pass in parameter.
After what you can inherit all your repositories from the "BaseRepository", and specify specific methods.
I made a simple example with 2 tables : https://dotnetfiddle.net/9hurx9
The best solution that I found is to create a generic class which depends of 2 types: The repository and the entity.
A BaseService< T1, T2 > which takes in parameter a "BaseRepository" and a "IEntity" and which will contain all the generic methods. This class must contain a property containing the instance of the repository. Thus, you can use the repository as shown in your example.
Then you can create specific Service classes, like a CarService which will inherit from BaseService< CarRepository, Car >.
A simple example, based on the example of my previous answer :
public class BaseService<TRepo, TEntity> where TRepo : BaseRepository<TEntity> where TEntity: IEntity
{
public TRepo Repository { get; set; }
public BaseService(TRepo repository)
{
this.Repository = repository;
}
public List<TEntity> GetAll()
{
return this.Repository.GetAll().ToList();
}
}
public class UserService : BaseService<UserRepository, User>
{
public UserService(UserRepository repository)
: base(repository)
{
}
public List<User> GetAllUserSortByName()
{
return this.Repository.GetAllUserSortByName();
}
}
You can use it like this :
YourEntities entities = new YourEntities();
UserRepository repo = new UserRepository(entities);
UserService service = new UserService(repo);
List<User> users = service.GetAllUserSortByName();
Let me know if my answer is not clear enough.
Edit :
Final example: https://dotnetfiddle.net/3s5BKZ
Thank you for you quick answer.
I managed to refactor my repositories and it's a really good point, thanks to your solution.
But at first my question was not about refactor my repositories but my services. I want to do the same process you did with the Entities.Set()... but with the call of my repositories.
Example:
I want to extract this method from my CarService :
public IQueryable<Car> GetAll()
{
return _carRepository.GetAll();
}
And put it in an abstract class Service. Something like :
public IQueryable<T> GetAll()
{
return Repository.GetAll();
}
But how to pass the right repository from the class CarService to the class Service ?
It's quiet hard to explain actually..
But thank you very much for the answer. It already helped me.
I've been banging my head with this for days and still can't decide on which is the correct approach.
This question is targeting WPF specifically since as opposed to a web-application, many posts and articles online recommends a context per view-model approach and not a context per request.
I have a WPF MVVM application which is using an Entity-Framework DB first model.
here is an example of two models used in my app (created by EF Designer):
public partial class User
{
public User()
{
this.Role = new HashSet<Role>();
}
public string ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Role> Role { get; set; }
}
public class Role
{
public Role()
{
this.User = new HashSet<User>();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<User> User { get; set; }
}
I've narrowed my options on how to handle this to the following:
1) Creating a DataAccess class which creates and disposes of the DbContext on each method call:
public class Dal
{
public User GetUserById(object userId)
{
using (var db = new DbEntities())
{
return db.User.Find(userId);
db.SaveChanges();
}
}
public void RemoveUser(User userToRemove)
{
using (var db = new DbEntities())
{
db.User.Remove(userToRemove);
db.SaveChanges();
}
}
}
which I can use in my ViewModel as follows:
public class UserManagerViewModel : ObservableObject
{
private readonly Dal dal = new Dal();
// models...
//commands...
}
2) Similar to approach 1 but without the Using statements:
public class Dal : IDisposable
{
private readonly DbEntities db = new DbEntities();
public User GetUserById(object userId)
{
return db.User.Find(userId);
db.SaveChanges();
}
public void RemoveUser(User userToRemove)
{
db.User.Remove(userToRemove);
db.SaveChanges();
}
public void Dispose()
{
db.SaveChanges();
}
}
The use is the same inside the ViewModel
3) Create a repository for each entity. Looks the same as the above options (also has the with or without the using dilemma), however every repository contains only methods related to its entity.
Afaik the use is the same as above inside my ViewModel.
4) Create a Unit-Of-Work class that will pass the appropriateRepository on demand:
public class UnitOfWork : IDisposable
{
private DbEntities db = new DbEntities();
private IUserRepository userRepository;
public IUserRepository UserRepository
{
get
{
return userRepository ?? new UsersRepository(db);
}
}
public void Save()
{
db.SaveChanges();
}
public void Dispose()
{
db.Dispose();
}
}
and use it inside my ViewModel as follows:
public class UserManagerViewModel : ObservableObject
{
private readonly UnitOfWork unit = new UnitOfWork();
// models...
//commands...
}
Which of the above approach (if any) is preferred in terms of in terms of data concurrency, better abstraction and layering and overall performance?
EDIT - Found the following paragraph in this article. :
When working with Windows Presentation Foundation (WPF) or Windows Forms, use a context instance per form. This lets you use change-tracking functionality that context provides.
However, it raises the question of whether I should create a DbContext object in my view-model or is it better to have a utility class such as my DAL class and reference it.
This is what dependency injection frameworks are designed to solve. Yes, it's yet another technology to add to your project, but once you start using DI you never look back.
The real problem here is that you're trying to make this decision in your view models when you really should be employing inversion of control and making the decision higher up. A WPF/MVVM application will want a context per-form so that changes are only submitted once a user is finished editing, and also to give the user the opportunity to cancel the changes. I know you're not using this in a web application but a well-designed architecture means you should be able to, in which case you'll want a context per request. You may want to write a console-app utility that populates the database with static data, in this case you may want a global/singleton context for performance and ease-of-use. Lastly, your unit tests also need to mock the context, probably on a per-test basis. All four of these cases should be set up in your injection framework and your view models should neither know or care about any of them.
Here's an example. I personally use Ninject, which is specifically designed for .NET. I also prefer NHibernate, although the choice of ORM is irrelevant here. I have session objects that have different scoping requirements, and this gets set up in a Ninject module that initializes my ORM classes:
var sessionBinding = Bind<ISession>().ToMethod(ctx =>
{
var session = ctx.Kernel.Get<INHibernateSessionFactoryBuilder>()
.GetSessionFactory()
.OpenSession();
return session;
});
if (this.SingleSession)
sessionBinding.InSingletonScope();
else if (this.WebSession)
sessionBinding.InRequestScope();
else
sessionBinding.InScope(ScreenScope);
This sets up the scoping for an ISession, which is the NHibernate equivalent of your context class. My repository classes, which manage the database objects in memory, contain a reference to the session they are associated with:
public class RepositoryManager : IRepositoryManager
{
[Inject]
public ISession Session { get; set; }
... etc...
{
The [Inject] attribute tells Ninject to populate this field automatically using the scoping rules I've set up. So far this is all happening in my domain classes, but it extends to my view model layer as well. In my scoping rules I pass in an object called "ScreenScope", and while I won't go into it here it basically means that any time I ask for a session object in my ScreenViewModel, or any view models that it has as members (including their own children) the same ISession object gets automatically created and passed in to all of them. By using DI scoping I don't even have to think about it, I just declare the members with the [Inject] attribute and it happens:
public class ScreenViewModel
{
[Inject] public CustomerService CustomerService { get; set; }
[Inject] public SalesService SalesService { get; set; }
[Inject] public BillService BillService { get; set; }
...etc...
}
These service classes all contains a RepositoryManager that has been injected, and since they're all in ScreenViewModel the ISession object will be the same, at least in my WPF build. if I switch to my MVC build they're the same for all view models created for a given request, and if I switch to a console build it uses the same ISession for everything in the entire program.
TL;DR: Use dependency injection and a scope your contexts to one-per-form.
In my earlier usage of MVVM within WPF I was utilising an open context per VM but I quickly ran into issues with thread safety of DBContexts once applications evolved to make better use of Async.
Whilst there is a greater development overhead, I now utilise dependency injection to provide a DBContextFactory (not the DBContext itself). I spin up a context in a using statement witihn the VM to fill observableCollections with plinq calls via EF. Another performance benefit of this method is running queries with AsNoTracking(). The annoying part is managing the reattachment of new or modified objects to the short lived context:
shortDBContext.Attach(myEntity).State = EntityState.Added; // or modified
await shortDBContext.SaveChangesAsync();
I have read from internet I got this points which says Interfaces is used for this
Use TDD methods
Replace persistance engine
But I'm not able to understand how interface will be usefull to this point Replace persistance engine.
lets consider I'm creating a basic(without generics) repository for EmployeeRepository
public class EmployeeRepository
{
public employee[] GetAll()
{
//here I'll return from dbContext or ObjectContex class
}
}
So how interfaces come into picture?
and if suppose i created an interface why upcasting is used ? for e.g
IEmployee emp = new EmployeeRepository() ;
vs
EmployeeRepository emp = new EmployeeRepository();
Please explain me precisely and also other usefullness of Interface in regard to Repository Pattern.
So how interfaces come into picture ?
Like this:
public interface IEmployeeRepository
{
Employee[] GetAll();
}
and then you could have as many implementations as you like:
public class EmployeeRepositoryEF: IEmployeeRepository
{
public Employee[] GetAll()
{
//here you will return employees after querying your EF DbContext
}
}
public class EmployeeRepositoryXML: IEmployeeRepository
{
public Employee[] GetAll()
{
//here you will return employees after querying an XML file
}
}
public class EmployeeRepositoryWCF: IEmployeeRepository
{
public Employee[] GetAll()
{
//here you will return employees after querying some remote WCF service
}
}
and so on ... you could have as many implementation as you like
As you can see it's not really important how we implement the repository. What's important is that all repositories and implementations respect the defined contract (interface) and all posses a GetAll method returning a list of employees.
And then you will have a controller which uses this interface.
public class EmployeesController: Controller
{
private readonly IEmployeeRepository _repository;
public EmployeesController(IEmployeeRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
var employees = _repository.GetAll();
return View(employees);
}
}
See how the controller no longer depends on a specific implementation of the repository? All it needs to know is that this implementation respects the contract. Now all that you need to do is to configure your favorite dependency injection framework to use the implementation you wish.
Here's an example of how this is done with Ninject:
Install the Ninject.MVC3 NuGet
In the generated ~/App_Start/NinjectWebCommon.cs code you simply decide to use the EF implementation with a single line of code:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IEmployeeRepository>().To<EmployeeRepositoryEF>();
}
This way you no longer need to do any manual instantiations of those repository classes and worry about upcasting or whatever. It is the dependency injection framework that manages them for you and will take care of injecting the defined implementation into the controller constructor.
And by simply modifying this configuration you could switch your data access technology without touching a single line of code in your controller. That's way unit testing in isolation also comes into play. Since your controller code is now weakly coupled to the repository (thanks to the interface we introduced) all you need to do in the unit test is to provide some mock implementation on the repository which allows you to define its behavior. This gives you the possibility to unit test the Index controller action without any dependency on a database or whatever. Complete isolation.
I also invite you to checkout the following articles about TDD and DI in ASP.NET MVC.
You would expose your repository as an interface:
public interface IEmployeeRepository
{
List<Employee> GetAll();
}
This would allow you to have many different implementations of the interface, such as the default one:
public class EmployeeRepository : IEmployeeRepository
{
public List<Employee> GetAll()
{
// Return from db.
}
}
Or a test one:
public class TestEmployeeRepository : IEmployeeRepository
{
public List<Employee> GetAll()
{
// Stub some dummy data.
}
}
Your code consuming the repository is then only interested in using the interface:
IEmployeeRepository myRepo = MyRepositoryFactory.Get<IEmployeeRepository>();
The secret sauce is the factory, or another mechanism by which to resolve the interface into a usable type (a Dependency Injection framework such as Ninject, or Castle Windsor will fulfil this role).
The point is, the consuming code doesn't care about the implementation, only the contract (the interface). This allows you to swap out implementations for testing purposes very easily and promotes loose coupling.
Just to clarify, there is no link between the use of interfaces and the repository pattern specifically, it is just another pattern that can make use of them.