MVC3 using EF4.3 and Dependancy Injection issues - asp.net-mvc-3

I have recently been learning MVC3 using Entity Framework 4.3 and Dependancy Injection so I can implement unit tests at a later date. I am now trying to implement some functions I have seen in various examples however I have hit a few issues that seem to stem from my use of dependancy injection and therefore I would like someone to point out where I am going wrong.
My first question is pretty simple; In most MVC3 examples I have seen, the access to the database is done in controllers, but when using dependancy injection I seem to need to refactor this code out to the implemented repository. Is this normal and correct?
My second more indepth issue is dealing with this simple example:
I have this method in my repository class which is pretty much copied from an online example (here). However I get an error regarding the Include part, and the intellisense does say that the variable needs to be a string. I have tried the original code from the link I mentioned earlier and that works fine, the only major difference between the project is that I am using dependancy injection.
public ExampleUser GetStruContractUser(int id)
{
ExampleUser user = context.ExampleUsers
.Include(i => i.ExampleRoles)
.Where(i => i.UserID == id)
.Single();
return user;
}
Changing the Include parameter to the following works fine.
public ExampleUser GetStruContractUser(int id)
{
ExampleUser user = context.ExampleUsers
.Include("ExampleRoles")
.Where(i => i.UserID == id)
.Single();
return user;
}
For reference this is my DbContext class that I am using:
public class EFDbContext : DbContext
{
public DbSet<ExampleUser> ExampleUsers { get; set; }
public DbSet<ExampleRole> ExampleRoles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<ExampleUser>().ToTable("User", "MySchema");
modelBuilder.Entity<ExampleRole>().ToTable("Role", "MySchema");
modelBuilder.Entity<ExampleUser>()
.HasMany(m => m.ExampleRoles)
.WithMany(t => t.ExampleUsers)
.Map(a =>
{
a.MapLeftKey("UserID"); // your PK column name in user table
a.MapRightKey("RoleID"); // your PK column name in role table
a.ToTable("UserRole", "MySchema"); // your join table name
});
}
}
Is this an issue due to my use of dependancy injection or is there something else going on that I am misunderstanding?
If you need more information, please ask and I will try and provide it.
Thanks very much.

Question 1:
Using DI doesn't force you to use a repository pattern, in fact they are not related. It's just a nice way to avoid tightly coupling your controller classes to the database context class, and being able to thus test those classes more easily. Repository gives you the ability to hide the implementation details of how you're accessing the DB, and allows you to switch ORM:s if that were to happen (and it never ever does). Repository relies on you to provide interfaces for your DbContext, and so does using DI.
What you want to do is use your DB through an interface nevertheless, and seeing as you're using DI, you could just inject the reference to the DbContext class in the constructor of your controllers, and let the DI controller do the work for you.
The reason it is preferable to pass in an interface that defines the repository to the Controller over passing an interface that defines your DbContext, is because making an interface of the latter can easily become overly complex, whereas sticking to a repository is much simpler. For simplicity though, I'd start with just using DbContext directly, and then expanding from there.
Question 2:
Include needs to contain the name of the table as a string. So your latter use of Include is correct, and the former isn't.
If I remember correctly, you can do this tho: ".Include(i => i.ExampleRoles.Name)" to achieve the same thing.

Yes, extracting your database layer (repositories / context) and then injecting it into your business layer (controllers) is very normal and a good way future proof your application. What if you ever wanted to change your database ORM from Entity Framework to something else? Having it tightly coupled with your controllers would create a huge headache.
Your second issue, with include, is unrelated to the dependancy injection.
Include on a dbset using lambdas an extension in System.Data.Entity. You'll need to include that reference if you want to use it.

Related

Domain driven design - access modifiers for entities and enforcing validation

I am very new to DDD and reading various discussions on validation (where to put it) on the stackoverflow as well as on the web. I do like the idea of keeping the validations outside the entities and validate them depending upon the context. In our project, we have an entity called MedicalRecord and there are various rules for when one can be created or can be saved. I want to create a service layer, let's say RecordService, that would do some check to make sure if a user can create a medical record before creating one. I also want to create MedicalRecordRepository that would save the medical record. What confuses me is the access modifies on my entity and repository classes. Since both will be public, how can I enforce the client of my application to use the service instead of just creating new medical record (with public constructor) and use the repository to save it? I am using c#. I know DDD is language independent but wondering if someone could provide some thoughts on this.
Thanks.
You must control record creation by making the c'tor non-public and allowing creation only through a factory:
public class MedicalRecord
{
internal MedicalRecord()
{
}
}
public static class MedicalRecordFactory
{
public static MedicalRecord Create(User onBehalfOf)
{
// do logic here
return new MedicalRecord();
}
}
For the internal keyword to be applicable, either both classes must be in the same assembly or the class assembly must allow the factory assembly access with the InternalsVisibleTo attribute.
Edit
If you need to be able to perform validation at any time, you additionally have to encapsulate validation logic in another class (here partially done via an extension method):
public static class MedicalRecordValidator
{
public static bool IsValid(this MedicalRecord medicalRecord, <context>)
{
return IsValid(<context>);
}
public static bool IsValidForCreation(User onBehalfOf)
{
return IsValid(null, onBehalfOf);
}
private static bool IsValid(<context> context, User user = null)
{
// do validation logic here
}
}
then, the factory could do this:
public static MedicalRecord Create(User onBehalfOf)
{
return IsValidForCreation(onBehalfOf) ? new MedicalRecord() : null;
}
and you could also always do this:
if (myMedicalRecord.IsValid(<context>))
{
// ....
Only use your repository to retrieve your entities; not to save them. Saving (persisting) your entities is the responsibility of your unit of work.
You let your service change one or more entities (for instance a MedicalRecord) and track the changes in a unit of work. Before committing the changes in your unit of work, you can validate all entities for validation needs across entities. Then you commit your unit of work (in a single transaction), which will persist all your changes, or none at all.
For clarity, your MedicalRecord should protect its own invariants; such that a client retrieving a MedicalRecord using a repository, calling some methods to modify it and then persisting it using a unit of work, should result in a "valid" system state. If there are situations where this is not the case, then it can be argued that it should not be possible to retrieve a MedicalRecord on its own - it is part of some larger concept.
For creation purposes, using a factory like #Thomas suggests below is a good approach, although I think I'd call it a service (because of the collaboration between entities) instead of a factory. What I like about Thomas' approach is that it does not allow a client to create a MedicalRecord without a User (or other contextual information), without tying the MedicalRecord tightly to the user.

Where to put my queries - model vs. controller

I just switched from ActiveRecord/NHibernate to Dapper. Previously, I had all of my queries in my controllers. However, some properties which were convenient to implement on my models (such as summaries/sums/totals/averages), I could calculate by iterating over instance variables (collections) in my model.
To be specific, my Project has a notion of AppSessions, and I can calculate the total number of sessions, plus the average session length, by iterating over someProject.AppSessions.
Now that I'm in Dapper, this seems confused: my controller methods now make queries to the database via Dapper (which seems okay), but my model class also makes queries to the database via Dapper (which seems strange).
TLDR: Should the DB access go in my model, or controller, or both? It seems that both is not correct, and I would like to limit it to one "layer" so that changing DB access style later doesn't impact too much.
You should consider using a repository pattern:
With repositories, all of the database queries are encapsulated within a repository which is exposed through public interface, for example:
public interface IGenericRepository<T> where T : class
{
T Get(object id);
IQueryable<T> GetAll();
void Insert(T entity);
void Delete(T entity);
void Save(T entity);
}
Then you can inject a repository into a controller:
public class MyController
{
private readonly IGenericRepository<Foo> _fooRepository;
public MyController(IGenericRepository<Foo> fooRepository)
{
_fooRepository = fooRepository;
}
}
This keeps UI free of any DB dependencies and makes testing easier; from unit tests you can inject any mock that implements IRepository. This also allows the repository to implement and switch between technologies like Dapper or Entity Framework without any client changes and at any time.
The above example used a generic repository, but you don't have to; you can create a separate interface for each repository, e.g. IFooRepository.
There are many examples and many variations of how repository pattern can be implemented, so google some more to understand it. Here is one of my favorite articles re. layered architectures.
Another note: For small projects, it should be OK to put queries directly into controllers...
I can't speak for dapper personally, but I've always restricted my db access to models only except in very rare circumstances. That seems to make the most sense in my opinion.
A little more info: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands. A passive implementation of MVC omits these notifications, because the application does not require them or the software platform does not support them.
Basically, data access in models seems to be the standard.
I agree with #void-ray regarding the repository model. However, if you don't want to get into interfaces and dependency injection you could still separate out your data access layer and use static methods to return data from Dapper.
When I am using Dapper I typically have a Repository library that returns very small objects or lists that can then be mapped into a ViewModel and passed to the View (the mapping is done by StructureMap, but could be handled in the controller or another helper).

MVC3 - EF4: One DbContext for all Repositories and ViewModels - UnitOfWork?

I'm totally stuck.
I've got two Controller: "Customer" and "Address". Both have the fields CustomerRepository and AddressRepository.
There are two ViewModels: CustomerViewModel and AddressViewModel. They also have the fields CustomerRepository and AddressRepository. (And also a parameterless constructor since they are parameters within the edit and create methods)
The Repositories themselves have a DbContext object from my Entities.
Now I'm running into one problem after another. I think I should have only ONE DbContext to share with all of my classes (Repositories AND ViewModels). And I think UnitOfWork is the solution. But I have no clue how to use that.
I currently tried to create a DbContext within the controllers constructor and pass it to every single object requiring it. But even that doesn't work.
If code is necessary, I will post it.
Couple of things to know:
1. Unit of Work
Unit of Work is not necessarily some kind of implementation for IUnitOfWork. It is just a pattern that might be applied in many ways. First, and foremost - you should understand what is it for before actually using it and overcomplicate things around. Moreover, EF Code-First DbContext API's DbContext is a kind of Unit of Work pattern. Your IDbSet<>s are your repositories. Don't try to abstract from your ORM, start with simplest possible thing.
2. DbContext injection
For the beginning, just inject the DbContext to your Controller with constructor injection. Don't forget to setup the IoC container of choice and wire up the MVC's DependencyResolver. Your controller could be look like (example also contains AutoMapper usage example, see next point about ViewModels for that):
public CustomerController : Controller
{
public CustomerController(MyDbContext data, IMappingEngine mapper)
{
Data = data;
Mapper = mapper;
}
public MyDbContext Data { get; set; }
public IMappingEngine Mapper { get; set; }
// Other controller code
}
3. View Models
This, again, is a pattern that is so easily implementable - just have your CustomerViewModel and use AutoMapper to easily transform your Customer to CustomerViewModel so that you can do it like this:
public ActionResult Details(int id)
{
var customer = Data.Customers.FirstOrDefault(c => c.Id == id);
if (customer == null)
return new HttpNotFoundResult();
return View(Mapper.Map<CustomerViewModel>(customer));
}
You can interrogate the AutoMapper's website on how to wire it up and make it running.
Notice that you don't get the ViewModel from DbContext directly. You obtain an "entity" instead which then transformed to appropriate View Model.
Hope this helps!
Your ViewModels should not have references to the DbContext or repositories. ViewModels should be largely stupid. It is the job of the controller (or a service called by the controller) to populate the ViewModels with the data the View needs.
Unit Of work is a good pattern, and one you should use.. but the patern is not a fix for your problem. Your problem is that you are making your view have too much knowledge of your data model.
I currently do the following:
One injected IUnitOfWork using unity to inject into my controllers.
IUnitOfWork implements IContext.
IContext contains IDbSet Customers and IDbSet
The concrete implementation of IContext implements DbContext.
My controllers reference a service, the service uses the IUnitOfWork.
If you use a repository, then simply use a single IContext injected into your controller (or IUnitOfWork which is fairly easy to add on top)
This way I have one context per lifetime of the request and then it's disposed. If you want more code let me know I'll see what I can post up here.

Using Ninject in a SOLID application architecture

I'm starting with MVC3 and want to use some flexible architecture, so I've read tens of blogs, a book (Pro ASP.NET MVC 3), read about SOLID principles and finally got to an application structure I like (or at least I think so, so far, because I haven't built anything on it yet):
In this structure:
Domain holds the POCO classes and defines the service interfaces
Services implements service interfaces and defines repositories interfaces
Data implements repositories interfaces
WebUI and Domain use Services
Services use Repositories
WebUI, Services and Data depend on Domain for POCO classes
The main reason for Domain using Services is to validate unique keys on the Validate methods of POCO (IValidatable) classes.
I'm starting to build a reference application with this structure but I have faced, so far, two problems:
I'm using a Data.Tests project with unit tests for the repositories, but haven't found a way to inject (using Ninject) a implementation of the service (in the constructor or otherwise) on the model, so the Validate method can call the CheckUniqueKey on the service.
I haven't found any reference about hooking up Ninject to a TEST project (lots of for the WebUI project).
What I'm trying to achive here is beeing able to switch from EF to something else like DAPPER, by just changing the DATA assembly.
UPDATE
Right now (as of 09-AUG-2011) Ninject is working but I think I'm missing something.
I have a CustomerRepository with two constructors:
public class CustomerRepository : BaseRepository<Customer>, ICustomerRepository
{
// The repository usually receives a DbContext
public CustomerRepository(RefAppContext context)
: base(context)
{
}
// If we don't receive a DbContext then we create the repository with a defaulte one
public CustomerRepository()
: base(RefApp.DbContext())
{
}
...
}
On the TestInitialize:
// These are for testing the Repository against a test database
[TestInitialize()]
public void TestInitialize()
{
// Context used for tests
this.context = new RefAppContext();
// This is just to make sure Ninject is working,
// would have used: repository = new CustomerRepository(context);
this.kernel = NinjectMVC3.CreateKernel();
this.kernel.Rebind<ICustomerRepository>().To<CustomerRepository>().WithConstructorArgument("context", context);
this.repository = kernel.Get<ICustomerRepository>();
}
On the Customer class:
public class Customer : IValidatableObject
{
...
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// I want to replace this with a "magic" call to ninject
CustomerRepository rep = new CustomerRepository();
Customer customer = rep.GetDupReferenceCustomer(this);
if (customer != null)
yield return new ValidationResult("Customer \"" + customer.Name + "\" has the same reference, can't duplicate", new [] { "Reference" });
}
...
}
What would be the best way to use Ninject in this scenario?
Any help will be highly appreciated.
ANSWER, SORT OF
I'll consider this question as aswered so far. I could get Ninject working, sort of, but it looks like achiving the Dependency Inversion Principle (DIP) of SOLID is going to take some more time.
In that respect, I had to lump together Domain, Services and Data, I'll create another question some other time and keep the project going the usual way for now.
Thanks everybody.
Unit testing should be done without Ninject. Just create an instance of the object under test and inject a mock for every dependency manually.
For Integration Tests you can use the kernel inclusive all bindings from the application bootstrapper and rebind everything you want to replace by a Mock. e.g. Replace the Session binding by one that uses an in memory data storage instead of a real database.

LINQ-to-XYZ polymorphism?

I have a situation where a client is requiring that we implement our data access code to use either an Oracle or SQL server database based on a runtime configuration settings. The production environment uses Oracle but both dev and QA are running against a SQL Server instance.
(I don't have any control over this or have any background on why this is the case other than Oracle is their BI platform and dev wants to work with SQL Server.)
Their request is to use LINQ-to-SQL / LINQ-to-Oracle for all data access. They will need to support the application and do not have the knowledge to jump into EF yet (their requirement) - although I believe the same problem exists if we use EF.
While I can implement LINQ to XYZ classes for both databases so that I can connect to both, they don't share a common interface (other than DataContext) so I really can't code against an interface and plug the actual implementation in at runtime.
Any ideas how I should approach this?
UPDATE
After writing this post, I did a little investigating into EF and it appears to me that this same problem exists if I use EF - which would be my long term goal.
Just a quick thought. Use MEF framework and plug your DAL layers to it. Then based on the environment(dev, production, QA) you can switch to the various DAL layers(Oracle, SQL etc.).
If you want to know about MEF , here is a quick intro.
Also sometime back I have seen a Generic Data Access Framework by Joydip Kanjilal. You can even have a look into that.
What you have to do is encapsulate the ORM datacontext in an interface of your creation, like IDataContext.
Then share this interface between all DALs and implement it. How you will plug it in is just your preference, using MEF as suggested or a IoC container.
For the sake of closure on this topic, here is what I ended up doing:
I implemented a combination of the Unit of Work and Repository patterns. The Unit of Work class is what consuming code works with and exposes all of the operations that can be performed on my root entities. There is one UoW per root entity. The UoW makes use of a repository class via an interface. The actual implementation of the repository is dependent on the data access technology being used.
So, for instance, if I have a customer entity and I need to support retrieving and updating each record, I would have something like:
public interface ICustomerManager
{
ICustomer GetCustomer(Guid customerId);
void SaveCustomer(ICustomer customer);
}
public class CustomerManager : ICustomerManager
{
public CustomerManager(ICustomerRepository repository)
{
Repository = repository;
}
public ICustomerRepository Repository { get; private set; }
public ICustomer GetCustomer(Guid customerId)
{
return Repository.SingleOrDefault(c => c.ID == customerId);
}
public void SaveCustomer(ICustomer customer)
{
Repository.Save(customer);
}
}
public interface ICustomerRepository : IQueryable<ICustomer>
{
void Save(ICustomer customer);
}
I'm using an Inversion of Control framework to inject the ICustomerRepository implementation into the CustomerManager class at runtime. The implementation class will be in a separate assembly that can be swapped out as the data access technology is changed. All we are concerned about is that the repository implements each method using the contract defined above.
As a side note, to do this with Linq-to-SQL, I simply created a LinqCustomerRepository class that implements ICustomerRepository and added a partial class for the generated Customer entity class that implements ICustomer. Then I can return the L2S entity from the repository as the implementation of the ICustomer interface for the UoW and calling code to work with and they'll be none the wiser that the entity originated from L2S code.

Resources