I am trying to learn how to use Dependency Injection on an auto-scaffolded controller in an MVC 5 Web application. While I have found tutorials on "Dependency Injection" and "Unity", the examples I have seen are more of the hello world variety and never actually get around to dealing with database contexts in controllers.
To give you a better example of what I mean, here is a code snippet of what I have and what I am trying to do.
When I use Visual Studio to auto-scaffold a controller "with views, using Entity Framework", this is typically what is created.
public class TideUploadsController : Controller
{
// This is the EF Database context placed by the auto-scaffolder
private AzMeritContext db = new AzMeritContext();
[HttpGet]
public ActionResult Index()
{
return View(db.TideUploads.ToList());
}
/* further CRUD ActionResults not shown */
}
}
From what I read so far, to use Dependency Injection, I should use a constructor that calls an interface instead of a class. I have read mixed reviews about wrapping a repository around Entity Framework. I would like to see if I could do this without use of a repository.
Is there a pre-existing interface I should use in place of the DbContext that is placed in the code by the auto-scaffolder?
// This is the EF Database context placed by the auto-scaffolder
private AzMeritContext db = new AzMeritContext();
public TideUploadsController(/* what Interface goes here? */)
{
//db = ?
}
Or is this a situation where I really need to wrap a repository around the Entity Framework dbContext?
I have spent the last few weeks reading books and searching through tutorials and videos, and I have not yet seen a step-by-step example that shows something like:
Step 1: Take the controller that you just auto-scaffolded
Step 2: Do this...
Step n: And now your controller is loosely-coupled with your database context rather than tightly-coupled.
Well, for me one of the benefits behind dependency injection is that you basically are decoupling your "dependencies" into mockable objects or other implementations, IMHO repository pattern is the common way to go, I don't see any other alternative of having to use a wrapper and configure you interface and your implementation in your container.
I guess you are familiar with the concept:
public class UserRepository:IUserRepository
{
public UserRepository(){
// you usually instanciate your context here
// private AzMeritContext db = new AzMeritContext();
}
User GetUserById(int Id){
// do your query to get a single user
}
}
this implementation looks ok to me.
then your controller should look like this:
public class TideUploadsController : Controller
{
public TideUploadsController(IUserRepository userRepository){
// constructor injection
// assign your user repository to a local variable outside of the constructor scope something like _userRepository
}
[HttpGet]
public ActionResult Index()
{
return View(_userRepository.GetUserById(1));
// let's assume your variable's name is _userRepository
}
/* further CRUD ActionResults not shown */
}
}
just remember that your interface should implement the methods you would like to use and expose in your controllers, services, etc.
my two cents, I hope that helps.
Related
I would like to ask some help regarding Dependency Injection and, I think, architectural approach.
So, I have an ORM layer implemented by EF6 where the objects are described and Ef does what its business, etc. I created a custom library over it, called DatabaseApi and it is mentioned in the title as "Api", where I query the data and map it to datacontract objects. I do it for pure testing purposes. I would like to have the different libraries in my application testable.
I started to implement the code where I inject the DbContext but I don't know how to deal with the usings in this case.
I went through a few blogposts and articles about mocking and EF, especially this one but it is rather about testing EF itself and not about how to decouple it from other libraries. On the other hand, I assume my search keywords were not proper.
Do you know any good and usable tutorials and articles about how to decouple entity framework from other libraries?
Thanks in advance!
Examples:
I created an empty interface in order to the DbContext can be injectable. It is implemented by the databaseContext.
public interface IDatabase
{
}
public class DatabaseModelContext : DbContext, IDatabase{
public DbSet<TableOne> TableOne { get; set; }
public DbSet<TableTwo> TableTwo { get; set; }
}
In the custom Api library constructor I put together a code to resolve the interface by Unity. I don't know whether it is working or not. I haven't executed yet.
public partial class DatabaseApi : IDatabaseApi {
private readonly IDatabase iDatabase;
private readonly UnityContainer unityContainer;
public DatabaseApi()
{
this.unityContainer = new UnityContainer();
this.unityContainer.RegisterType<IDatabase, DatabaseModelContext>();
this.iDiLibDatabase = this.unityContainer.Resolve<IDiLibDatabase>();
}
}
And here is the problem. Due to the injection I'll have and interface but there are the usings which are important to manage the resource as far as I know. How to do it?
public partial class DatabaseApi : IDatabaseApi
{
public List<SomeDataContract> GetMainStructure()
{
var result = new List<SomeDataContract>();
//this is the old implementation
using (var database = new DatabaseModelContext())
{
//some data manipulation magic... :)
}
return result;
}
If you're okay using linq to objects as a core element of your domain access layer then exposing an IQueryable for access to the entities would work...
public interface IRepository<TEntity>
{
IQueryable<TEntity> AllEntities { get; }
}
With that, you can do your Where, Select, etc. without hard wiring directly to EF. Behind the scenes the IRepository implementations would deal with the EF portions, database connectivity, etc. There's no avoiding coupling the to EF at the data access layer. But you can keep it constrained to just that layer using something like you've started. Just make sure the database contexts used by your IRepository objects are the only objects working with EF.
Put another way: Don't have your IDatabase return entities. Just have it deal with the connections, and you should create another layer for domain object access which takes in an IDatabase. In the example I gave, somehow the IRepository implementations would take in an instance of IDatabase.
So, the solution is using Autofac DI framework. I found interesting questions and answers and two really helpful tutorials. Links below:
How do you reconcile IDisposable and IoC?
Dependency Injection with Autofac
Generic Repository and Unit of Work Pattern, Entity Framework, Unit Testing, Autofac IoC Container and ASP.NET MVC
Autofac homepage
I love the Unity and Ninject framework with dependency injection for C#.NET into the controllers with repository interfaces etc, but I am trying to think up an alternative in PHP and am struggling.
I have:
class User
{
//..
}
interface IUserRepository
{
public function Repository(); // This can't work as a variable, should I abstract?
}
class UserRepository implements IUserRepository
{
public function Repository()
{
$users = // DAO gets users and returns them..
// But how does the IUserRepository help me at all? Even if I had ninject or
// Unity creating some new link between the UserRepo and IUserRepo?
return $users;
}
public function GetAllUsers()
{
// errr.. I'm confused
}
}
// Something has to say if the AdminController is called,
// inject into its construct, a new IUserRepository
class AdminController extends Controller
{
private $repository;
public function __Construct( $repository )
{
$this->repository = $repository;
}
public function ActionResult_ListUsers()
{
$users = $repository->GetAllUsers();
// Do some clever View method thing with $users as the model
}
}
The real question is PHP and repository approach. How does that work? You can see I'm blotching this a bit and really want to get it right!
EDIT::
Even more simple question. What is the benefit of the interface keyword? How does declaring an interface with some methods undefined and then making a new class that implements those methods to extend them, help when you cannot create a new interface like a class that then is filled in with the proper class that defines them?
Kind of a broad question but I'll take a shot. Symfony 2 is a modern php framework built around an excellent dependency injection container. Symfony 2 supports Doctrine 2 which is a modern orm persistence layer in which repositories are supported.
Skim through here: http://symfony.com/doc/current/book/doctrine.html
Skip all the details on setting things up and instead look for:
Creating an Entity Class
Persisting Objects to the Database
Fetching Objects from the Database
The fetching section is where repositories come into play. This gives you a broad overview of one way to implement repositories on php. You might decide to research more on Symfony 2/Doctrine 2 or you may go another route entirely. But this will give you a starting point.
As far as interfaces go, I hate to say it but that is a real real real basic question. Might want to go through some OOP tutorials? A one or two sentence explanation is probably not going to make much sense.
====================================================
This may help a bit:
class User
{
//..
}
interface IUserRepository
{
public function getAllUsers();
}
class UserRepository extends DoctrineRepository implements IUserRepository
{
public function getAllUsers()
{
return $this->findAll();
}
}
class AdminController extends Controller
{
private $repository;
public function __Construct(IUserRepository $repository )
{
$this->repository = $repository;
}
public function ActionResult_ListUsers()
{
$users = $this->repository->getAllUsers();
// Do some clever View method thing with $users as the model
}
Your User and IUserRepository would reside in what is known as a domain layer.
The actual UserRepository implementation would be in a service layer. You might have multiple implementations. One talking to a sql database. Perhaps another talking to MongoDB or maybe just a file.
You controller lives in yet another layer. It expects to receive an object the implements an IUserRepository and thus has a getAllUsers method. Your controller does not care how the repository is actually implemented. All it knows is what is exposed via the interface.
It's up to your application to wire things up using dependency injection such that the controller gets the correct repository.
I'm working on a system where I'd like to have my layers decoupled as much as possible, you know, some kind of modular application to be able to switch databases and stuff without a serious modification of the rest of the system.
So, I've been watching for x-the time one of the talks of Robert C. Martin about good practices, clean code, decoupling architecture etc, to get some inspiration. What I find kinda weird is his description of the system Fitnesse and the way they've implemented store/load methods for WikiPages. I'm linking the video as well: Robert C. Martin - Clean Architecture and Design
What's he describing (at least from my understanding) is that the entity is aware of the mechanism how to store and load itself from some persistent layer. When he wanted to store WikiPages in-memory, he simply overrode the WikiPage and created a new InMemoryWikiPage. When he wanted to store them in a database, he did the same thing...
So, one of my questions is - what is this approach called? I've been learning the whole time about Repository patterns and stuff, and why should be classes like this persistence-ignorant, but I can't seem to find any materials on this thing he did. Because my application will consist of modules, I think this may help to solve my problems without a need for creating some centralized store for my entities... Every module would simply take care of itself including persistence of its entities.
I think the code would look like is something like this:
public class Person : IEntity
{
public int ID { get;set; }
public string Name { get;set; }
public void Save()
{
..
}
public void Update()
{
}
public void Delete()
{
}
...
}
Seems a bit weird, but... Or maybe I misunderstood what he said in the video?
My second question would be, if you don't agree with this approach, what would be the path you'd take in such modular application?
Please provide an example if possible with some explanation.
I'll answer your second question. I think you will be interested as well in Dependency Injection.
I'm not an expert on DI but I'll try to explain as clear as I'm able to.
First off, from wikipedia:
Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.
The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time.
There are many libraries around that help you implement this design pattern: AutoFac, SimpleInjector, Ninject, Spring .NET, and many others.
In theory, this is what your code would look like (AutoFac example)
var containerBuilder = new ContainerBuilder();
//This is your container builder. It will be used to register interfaces
// with concrete implementations
Then, you register concrete implementations for interface types:
containerBuilder.RegisterType<MockDatabase>().As<IDatabase>().InstancePerDependency();
containerBuilder.RegisterType<Person>().As<IPerson>().InstancePerDependency();
In this case, InstancePerDependency means that whenever you try to resolve IPerson, you'll get a new instance. It could be for example SingleInstance, so whenever you tried to resolve IPerson, you would get the same shared instance.
Then you build your container, and use it:
var container = containerBuilder.Build();
IPerson myPerson = container.Resolve<IPerson>(); //This will retrieve the object based on whatever implementation you registered for IPerson
myPerson.Id = 1;
myPerson.Save(); //Save your changes
The model I used in this example:
interface IEntity
{
int Id { get; set; }
string TableName { get; }
//etc
}
interface IPerson: IEntity
{
void Save();
}
interface IDatabase
{
void Save(IEntity entity);
}
class SQLDatabase : IDatabase
{
public void Save(IEntity entity)
{
//Your sql execution (very simplified)
//yada yada INSERT INTO entity.TableName VALUES (entity.Id)
//If you use EntityFramework it will be even easier
}
}
class MockDatabase : IDatabase
{
public void Save(IEntity entity)
{
return;
}
}
class Person : IPerson
{
IDatabase _database;
public Person(IDatabase database)
{
this._database = database;
}
public void Save()
{
_database.Save(this);
}
public int Id
{
get;
set;
}
public string TableName
{
get { return "Person"; }
}
}
Don't worry, AutoFac will automatically resolve any Person Dependencies, such as IDatabase.
This way, in case you wanted to switch your database, you could simply do this:
containerBuilder.RegisterType<SqlDatabase>().As<IDatabase>().InstancePerDependency();
I wrote an over simplified (not suitable for use) code which serves just as a kickstart, google "Dependency Injection" for further information. I hope this helps. Good luck.
The pattern you posted is an Active Record.
The difference between Repository and Active Record Pattern is that in Active Record pattern, data query and persistence, and the domain object are in one class, where as in Repository, the data persistence and query are decoupled from the domain object itself.
Another pattern that you may want to look into is the Query Object which, unlike respository pattern where its number of methods will increase in every possible query (filter, sorting, grouping, etc) the query object can use fluent interface to be expressive [1] or dedicated in which one you may pass parameter [2]
Lastly, you may look at Command Query Responsibility Segregation architecture for ideas. I personally loosely followed it, just picked up ideas that can help me.
Hope this helps.
Update base on comment
One variation of Repository pattern is this
UserRepository
{
IEnumerable<User> GetAllUsers()
IEnumerable<User> GetAllByStatus(Status status)
User GetUserById(int id)
...
}
This one does not scale since the repository get's updated for additional query that way be requested
Another variation is to pass query object as parameter to the data query
UserRepository
{
IEnumerable<User> GetAll(QueryObject)
User GetUserById(int id)
...
}
var query = new UserQueryObject(status: Status.Single)
var singleUsers = userRepo.GetAll(query)
Some in .Net world, Linq expression is passed instead of QueryObject
var singleUsers = userRepo.GetAll(user => user.Status == Status.Single)
Another variation is to do dedicate Repository for retrieval on one entity by its unique identifier and save it, while query object is used to submit data retrieval, just like in CQRS.
Update 2
I suggest you get familiar with the SOLID principles. These principles are very helpful in guiding you creating a loosely coupled, high cohesive architecture.
Los Techies compilation on SOLID pricples contains good introductory articles regarding SOLID priciples.
Is it possible to expose the DataContext when extending a class in the DataContext? Consider this:
public partial class SomeClass {
public object SomeExtraProperty {
this.DataContext.ExecuteQuery<T>("{SOME_REALLY_COMPLEX_QUERY_THAT_HAS_TO_BE_IN_RAW_SQL_BECAUSE_LINQ_GENERATES_CRAP_IN_THIS INSTANCE}");
}
}
How can I go about doing this? I have a sloppy version working now, where I pass the DataContext to the view model and from there I pass it to the method I have setup in the partial class. I'd like to avoid the whole DataContext passing around and just have a property that I can reference.
UPDATE FOR #Aaronaught
So, how would I go about writing the code? I know that's a vague question, but from what I've seen online so far, all the tutorials feel like they assume I know where to place the code and how use it, etc.
Say I have a very simple application structured as (in folders):
Controllers
Models
Views
Where do the repository files go? In the Models folder or can I create a "Repositories" folder just for them?
Past that how is the repository aware of the DataContext? Do I have to create a new instance of it in each method of the repository (if so that seems in-efficient... and wouldn't that cause problems with pulling an object out of one instance and using it in a controller that's using a different instance...)?
For example I currently have this setup:
public class BaseController : Controller {
protected DataContext dc = new DataContext();
}
public class XController : BaseController {
// stuff
}
This way I have a "global" DataContext available to all controllers who inherit from BaseController. It is my understanding that that is efficient (I could be wrong...).
In my Models folder I have a "Collections" folder, which really serve as the ViewModels:
public class BaseCollection {
// Common properties for the Master page
}
public class XCollection : BaseCollection {
// X View specific properties
}
So, taking all of this where and how would the repository plug-in? Would it be something like this (using the real objects of my app):
public interface IJobRepository {
public Job GetById(int JobId);
}
public class JobRepository : IJobRepository {
public Job GetById(int JobId) {
using (DataContext dc = new DataContext()) {
return dc.Jobs.Single(j => (j.JobId == JobId));
};
}
}
Also, what's the point of the interface? Is it so other services can hook up to my app? What if I don't plan on having any such capabilities?
Moving on, would it be better to have an abstraction object that collects all the information for the real object? For example an IJob object which would have all of the properties of the Job + the additional properties I may want to add such as the Name? So would the repository change to:
public interface IJobRepository {
public IJob GetById(int JobId);
}
public class JobRepository : IJobRepository {
public IJob GetById(int JobId) {
using (DataContext dc = new DataContext()) {
return dc.Jobs.Single(j => new IJob {
Name = dc.SP(JobId) // of course, the project here is wrong,
// but you get the point...
});
};
}
}
My head is so confused now. I would love to see a tutorial from start to finish, i.e., "File -> New -> Do this -> Do that".
Anyway, #Aaronaught, sorry for slamming such a huge question at you, but you obviously have substantially more knowledge at this than I do, so I want to pick your brain as much as I can.
Honestly, this isn't the kind of scenario that Linq to SQL is designed for. Linq to SQL is essentially a thin veneer over the database; your entity model is supposed to closely mirror your data model, and oftentimes your Linq to SQL "entity model" simply isn't appropriate to use as your domain model (which is the "model" in MVC).
Your controller should be making use of a repository or service of some kind. It should be that object's responsibility to load the specific entities along with any additional data that's necessary for the view model. If you don't have a repository/service, you can embed this logic directly into the controller, but if you do this a lot then you're going to end up with a brittle design that's difficult to maintain - better to start with a good design from the get-go.
Do not try to design your entity classes to reference the DataContext. That's exactly the kind of situation that ORMs such as Linq to SQL attempt to avoid. If your entities are actually aware of the DataContext then they're violating the encapsulation provided by Linq to SQL and leaking the implementation to public callers.
You need to have one class responsible for assembling the view models, and that class should either be aware of the DataContext itself, or various other classes that reference the DataContext. Normally the class in question is, as stated above, a domain repository of some kind that abstracts away all the database access.
P.S. Some people will insist that a repository should exclusively deal with domain objects and not presentation (view) objects, and refer to the latter as services or builders; call it what you like, the principle is essentially the same, a class that wraps your data-access classes and is responsible for loading one specific type of object (view model).
Let's say you're building an auto trading site and need to display information about the domain model (the actual car/listing) as well as some related-but-not-linked information that has to be obtained separately (let's say the price range for that particular model). So you'd have a view model like this:
public class CarViewModel
{
public Car Car { get; set; }
public decimal LowestModelPrice { get; set; }
public decimal HighestModelPrice { get; set; }
}
Your view model builder could be as simple as this:
public class CarViewModelService
{
private readonly CarRepository carRepository;
private readonly PriceService priceService;
public CarViewModelService(CarRepository cr, PriceService ps) { ... }
public CarViewModel GetCarData(int carID)
{
var car = carRepository.GetCar(carID);
decimal lowestPrice = priceService.GetLowestPrice(car.ModelNumber);
decimal highestPrice = priceService.GetHighestPrice(car.ModelNumber);
return new CarViewModel { Car = car, LowestPrice = lowestPrice,
HighestPrice = highestPrice };
}
}
That's it. CarRepository is a repository that wraps your DataContext and loads/saves Cars, and PriceService essentially wraps a bunch of stored procedures set up in the same DataContext.
It may seem like a lot of effort to create all these classes, but once you get into the swing of it, it's really not that time-consuming, and you'll ultimately find it way easier to maintain.
Update: Answers to New Questions
Where do the repository files go? In the Models folder or can I create a "Repositories" folder just for them?
Repositories are part of your model if they are responsible for persisting model classes. If they deal with view models (AKA they are "services" or "view model builders") then they are part of your presentation logic; technically they are somewhere between the Controller and Model, which is why in my MVC apps I normally have both a Model namespace (containing actual domain classes) and a ViewModel namespace (containing presentation classes).
how is the repository aware of the DataContext?
In most instances you're going to want to pass it in through the constructor. This allows you to share the same DataContext instance across multiple repositories, which becomes important when you need to write back a View Model that comprises multiple domain objects.
Also, if you later decide to start using a Dependency Injection (DI) Framework then it can handle all of the dependency resolution automatically (by binding the DataContext as HTTP-request-scoped). Normally your controllers shouldn't be creating DataContext instances, they should actually be injected (again, through the constructor) with the pre-existing individual repositories, but this can get a little complicated without a DI framework in place, so if you don't have one, it's OK (not great) to have your controllers actually go and create these objects.
In my Models folder I have a "Collections" folder, which really serve as the ViewModels
This is wrong. Your View Model is not your Model. View Models belong to the View, which is separate from your Domain Model (which is what the "M" or "Model" refers to). As mentioned above, I would suggest actually creating a ViewModel namespace to avoid bloating the Views namespace.
So, taking all of this where and how would the repository plug-in?
See a few paragraphs above - the repository should be injected with the DataContext and the controller should be injected with the repository. If you're not using a DI framework, you can get away with having your controller create the DataContext and repositories, but try not to cement the latter design too much, you'll want to clean it up later.
Also, what's the point of the interface?
Primarily it's so that you can change your persistence model if need be. Perhaps you decide that Linq to SQL is too data-oriented and you want to switch to something more flexible like Entity Framework or NHibernate. Perhaps you need to implement support for Oracle, mysql, or some other non-Microsoft database. Or, perhaps you fully intend to continue using Linq to SQL, but want to be able to write unit tests for your controllers; the only way to do that is to inject mock/fake repositories into the controllers, and for that to work, they need to be abstract types.
Moving on, would it be better to have an abstraction object that collects all the information for the real object? For example an IJob object which would have all of the properties of the Job + the additional properties I may want to add such as the Name?
This is more or less what I recommended in the first place, although you've done it with a projection which is going to be harder to debug. Better to just call the SP on a separate line of code and combine the results afterward.
Also, you can't use an interface type for your Domain or View Model. Not only is it the wrong metaphor (models represent the immutable laws of your application, they are not supposed to change unless the real-world requirements change), but it's actually not possible; interfaces can't be databound because there's nothing to instantiate when posting.
So yeah, you've sort of got the right idea here, except (a) instead of an IJob it should be your JobViewModel, (b) instead of an IJobRepository it should be a JobViewModelService, and (c) instead of directly instantiating the DataContext it should accept one through the constructor.
Keep in mind that the purpose of all of this is to keep a clean, maintainable design. If you have a 24-hour deadline to meet then you can still get it to work by just shoving all of this logic directly into the controller. Just don't leave it that way for long, otherwise your controllers will (d)evolve into God-Object abominations.
Replace {SOME_REALLY_COMPLEX_QUERY_THAT_HAS_TO_BE_IN_RAW_SQL_BECAUSE_LINQ_GENERATES_CRAP_IN_THIS INSTANCE} with a stored procedure then have Linq to SQL import that function.
You can then call the function directly from the data context, get the results and pass it to the view model.
I would avoid making a property that calls the data context. You should just get the value from a service or repository layer whenever you need it instead of embedding it into one of the objects created by Linq to SQL.
I'm a bit confused about when using the "IRepository pattern", when actually to load the data.
Currently I have something like this:
public class MainViewModel : ViewModelBase
{
// EF4 generated ObjectContext
private ScorBotEntities context = new ScorBotEntities();
// Custom IUserRepository class
private IUserRepository userRepository;
public MainViewModel()
{
this.userRepository = new UserRepository(context.Users);
}
public ObservableCollection<User> Users
{
get
{
return new ObservableCollection<User>(userRepository.GetAll());
}
}
}
ScorBotEntities are autogenerated using EF4 (I had a look at POCOs, to much work for this sized project).
You can find the definition of the UserRepository here: http://code.google.com/p/i4prj4-g2/source/browse/ScorBotRobotics/ScorBotRobotics/Repositories/UserRepository.cs
But basically, what I'm wondering about is, why do it even make sense to use a repository here, instead of just writing it like this:
public class MainViewModel : ViewModelBase
{
private ScorBotEntities context = new ScorBotEntities();
public MainViewModel()
{
}
public ObservableCollection<User> Users
{
get
{
return new ObservableCollection<User>(context.Users);
}
}
}
It makes sense to abstract functionality away such as with the UsernameAndPassword method. But in that case, perhaps using some Query Objects would be more ideal?
I am a bit baffled that your context has made its way down to your ViewModel. I believe your GUI layer should never see the context. Context must be opened/kept/closed by the IRepository. Let the data layer (IRepository) return an array/list of Users.
There are a couple of different points here. First, your view models should have no knowledge of the repository - keep your view models as simple as possible.
Second, the IRepository is your public API - so you should have dependencies to this (depend on abstractions rather than concrete implementation between layers).
There are a couple of different (perfectly acceptable ways) to implement the IRepository. One is to have the repository encapsulate the context directly. Another is to use the "unit of work" pattern and have your unitOfWork encapsulate the context and pass the unitOfWork object to each repository. Either way, since you're using EF4, testability is much easier than it used to be. For example, EF4 introduced IObjectSet so that it is easy to provide test doubles and mocks to test your repository.
I highly recommend checking out this whitepaper on Testability and Entity Framework 4.
Separation of concerns
What if you want to change the storage of 'Users', from say SQL to a flat file?
Then context would not be needed, and you'd have to change every use of it, instead of just your IRepository implementation.
Also, ideally you would have your IRepository injected. So you're MainViewModel doesn't care how it gets it's Users.