How to execute Queries with multiple models in Entity framework with Dependency Injection - asp.net-mvc-3

I tried using Dependency Injection with Entity framework in my MVC application. In the project I have defined Generic Repository class for CRUD operations. There are concrete service classes for each model object. My Controller in Presentation layer uses Concrete classes of Service layer to get data from database. These concrete classes in turn calls RepositoryClass methods to implement actual operation with database.
Below is sample of the class definations (for simplicity I have removed various interfaces details and implementation of some methods):
class RepositoryBase<T>
{
Add(T entity) {...}
Update (T entity) {...}
Delete (T entity) {...}
T GetById(int id) {...}
IEnumerable<T> GetAll()
{dbContext.ToList();}
}
public class CarsService {
public IEnumerable<Cars> GetCars()
{
var cars = RepositoryBase<Cars>.GetAll();
return cars;
}
public Car GetCar(int id)
{
var car = RepositoryBase<T>.GetById(id);
return car;
}
}
Public class DealerService {...}
All this works great as long as I have to deal with 1 object type at a time in my application. But I am not sure how to make change in service class to get data for multiple entities i.e. Car and dealers togather. Please note in my scenario although i have dealer id defined in Cars model but navigation property is missing. So I have to join Cars and Dealers using linq query.
Please help to identify correct class (layer) which needs to be modified. All the examples I have found only talks about 1 entity at a time.

DbContext.Set().Include()first of all you put you config mapping for fixing,
second if you don't want to use navigation properties , you can use
RepositoryBase<Cars>.GetEntitySet<Cars>.Include("Dealers") //this does join if you key to join
but in this case you should use the
add to RepositoryBase<T> a property
public ISet<T> GetEntitySet<T>(string table2Include)
{
return DbContext.Set<T>()
}

Related

How to avoid Spring Repository<T, ID> to leak persistence information into service tier

I'm using spring-data-mongodb at the moment so this question is primarily in context of MongoDB but I suspect my question applies to repository code in general.
Out of the box when using a MongoRepository<T, ID> interface (or any other Repository<T, ID> descendent) the entity type T is expected to be the document type (the type that defines the document schema).
As a result injecting such a repository into service component means this repository is leaking database schema information into the service tier (highly pseudo) :
class MyModel {
UUID id;
}
#Document
class MyDocument {
#Id
String id;
}
interface MyRepository extends MongoRepository<MyDocument, String> {
}
class MyService {
MyRepository repository;
MyModel getById(UUID id) {
var documentId = convert(id, ...);
var matchingDocument = repository.findById(documentId).orElse(...);
var model = convert(matchignDocument, ...);
return model;
}
}
Whilst ideally I'd want to do this :
class MyModel {
UUID id;
}
#Document
class MyDocument {
#Id
String id;
}
#Configuration
class MyMagicConversionConfig {
...
}
class MyDocumentToModelConverter implements Converter<MyModel, MyDocument> {
...
}
class MyModelToDocumentConverter implements Converter<MyDocument, MyModel> {
...
}
// Note that the model and the model's ID type are used in the repository declaration
interface MyRepository extends MongoRepository<MyModel, UUID> {
}
class MyService {
MyRepository repository;
MyModel getById(UUID id) {
// Repository now returns the model because it was converted upstream
// by the mongo persistence layer.
var matchingModel = repository.findById(documentId).orElse(...);
return matchingModel ;
}
}
Defining this conversion once seems significantly more practical than having to consistently do it throughout your service code so I suspect I'm just missing something.
But of course this requires some way to inform the mongo mapping layer to be aware of what conversion has to be applied to move between MyModel and MyDocument and to use the latter for it's actual source of mapping metadata (e.g. #Document, #Id, etc.).
I've been fiddling with custom converters but I just can't seem to make the MongoDB mapping component do the above.
My two questions are :
Is it currently possible to define custom converters or implement callbacks that allow me to define and implement this model <-> document conversion once and abstract it away from my service tier.
If not, what is the idiomatic way to approach cleaning this up such that the service layer can stay blissfully unaware of how or with what schema an entity is persisted? A lot of Spring Boot codebases appear to be fine with using the type that defines the database schema as their model but that seems supoptimal. Suggestions welcome!
Thanks!
I think you're blowing things a bit out of proportion. The service layer is not aware of the schema. It is aware of the types returned by the repository. How the properties of those are mapped onto the schema, depends on the object-document mapping. This, by default, uses the property name, as that's the most straightforward thing to do. That translation can either be customized using annotations on the document type or by registering a FieldNamingStrategy with Spring Data MongoDB.
Spring Data MongoDB's object-document mapping subsystem provides a lot of customization hooks that allows transforming arbitrary MongoDB documents into entities. The types which the repositories return are your domain objects that - again, only by default - are mapped onto a MongoDB document 1:1, simply because that's the most reasonable thing to do in the first place.
If really in doubt, you can manually implement repository methods individually that allow you to use the MongoTemplate API that allows you to explicitly define the type, the data should be projected into.
You can use something like MapStruct or write your own Singleton Mapper.
Then create default methods in your repository:
interface DogRepository extends MongoRepository<DogDocument, String> {
DogDocument findById(String id);
default DogModel dogById(String id) {
return DogMapper.INSTANCE.toModel(
findById(id)
);
}
}

N-Tier Service Layer Validation Show Business Logic Error in Presentation Layer

I am converting from the old ways of ASP.NET Web Forms to ASP.NET MVC. I have a project that I am working on that has about 40-50 tables in the database. I have decided to use Entity Framework as my data access layer. I have also decided to put a repository layer and unit of work abstraction over EF so that I am not tied to it and so that I can do unit testing. Finally, I want to make my controllers "thin" so I am looking at implementing a business "service" layer for my business logic.
The thing I am struggling with is how do I propagate Business Logic Errors from my service layer to my Presentation UI layer so that an appropriate error can be shown? Please note that I am trying to look for a solution that is NOT MVC specific as this service/business logic layer will likely be used in other things besides an MVC app (console app's, web services, etc.)
On to some code...
Lets say I have a POCO / data / domain model like so:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
// other properties (navigation, etc)...
}
An Entity Framework fluent configuration/mapping class like so:
public class CategoryMap : EntityTypeConfiguration<Category>
{
public CategoryMap()
{
this.HasKey(c => c.Id);
this.Property(c => c.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // auto increment identity in our DB schema
this.Property(c=> c.Name)
.IsRequired() // defined as NOT NULL in DB schema so we put a constraint here
.HasMaxLength(150); // defined as varchar(150) in DB schema so we put a constraint here
this.Property(c=> c.Description)
.IsRequired(); // defined as NOT NULL in DB schema so we put a constraint here
// fluent config for related entities (navigation properties) would go here...
}
}
A unit of work encapsulating multiple repositories like so:
public class UnitOfWork : IUnitOfWork
{
private readonly MyDbContext context;
private CategoryRepository catRepo;
public UnitOfWork()
{
this.context = new MyDbContext();
}
public ICategoryRepository Categories
{
get { return this.catRepo?? (this.catRepo= new CategoryRepository (this.context)); }
}
}
A service / business logic layer like so:
public class CategoryService : ICategoryService
{
private readonly IUnitOfWork unitOfWork;
public CategoryService(IUnitOfWork uow) // injected by IoC
{
this.unitOfWork = uow;
}
public Category CreateNewCategory(Category category)
{
if (category == null)
{
throw new ArgumentNullException("category cannot be null");
}
// Simple business logic here to make sure another category with this name does not already exist.
int count = this.unitOfWork.Categories.Count(cat => cat.Name == category.Name);
if (count > 0)
{
// *** This is the error I want the user to see in the UI ***
throw new Exception("Sorry - a category with that name already exists!");
}
}
}
And a controller like this:
public ManageCategoriesController : Controller
{
ICategoryService catSvc;
public ManageCategoriesController(ICategoryService svc) // injected by IoC
{
this.catSvc = svc;
}
[HttpPost]
public ActionResult(CategoryCreateModel createModel) // my View Models / Create Models have Data Annotations on them
{
if (ModelState.IsValid)
{
// use of AutoMapper to map from View Model to domain model...
Category cat = Mapper.Map<CategoryCreateModel , Category>(createModel);
this.catSvc.CreateNewCategory(cat); // ***need to get potential errors from Service and display on form.***
return this.RedirectToAction("Index");
}
}
}
First of all, can anybody tell me if I am on the right track with using View Models? I feel like I almost have three View Models (Create, Edit, View/List) per domain model.
Secondly, my EF configuration/mapping class takes care of the database constraints. Some of these constraints (e.g. Max length) are also data annotations in the View Models and can easily be displayed on the UI. But where can I show my custom business logic errors?
First, your overall approach to MVC looks good to me :-)
Second, you most likely want to use DataAnnotation on your view models for model validation. Have a look this blog post for a good intro on using it in ASP.MVC.
In case of custom validation not suitable for data annotation you can do the following in your controller:
try
{
// the following exception could be thown by some nested validation logic
// e.g. while processing a post request
throw new ValidationException("the error description");
}
catch (ValidationException exception)
{
ModelState.AddModelError("", exception.Message);
}
This is a pretty old question, but for future readers I'd like to add something.
If you're actually using a N-Tier pattern, entity validation should be in your Service layer. Not in your MVC Controller.
The right way to do it is to do basic model validations in your model class, using ValidationAttributes, but re-validate your entities in your service layer.
Add a handling of custom exceptions in your controller to catch any validation error raised from the service layer, and display error messages.
If your service layer is just there to call your repositories, you're doing something wrong ;)

Is there a recommended base repository class to use with Entity Framework?

I'm using an EF Code First approach with an ASP.NET MVC 3 application, and instead of re-creating the wheel, I was wondering if there already exists a solid base Repository class that my custom Repository classes could extend in order to provide default functionality out of the box (e.g. basic CRUD, etc...).
So something like this ...
public class CustomerRepository : BaseRepository { ... }
... would therefore provide a default way to work with Customer objects out of the box. I'd like to then inject an ICustomerRepository into my MVC controllers and have the functionality available to me there.
I'm sure something like this already exists out there as I've done something similar with NHibernate.
Thanks
No, there is no built-in repository, other than EF itself (which is in and of itself an implementation of the Unit of Work pattern, and DbSet's are basically Repositories).
There is currently a debate in the software community over whether generic repositories have much real value. For testing purposes, many argue, they provide easy unit testing. Others say that unit testing repositories doesn't help because mocked repositories don't behave the same way that real ones do (because of the linq -> Sql translation layer, which doesn't exist in a mocked repository).
Many are suggesting that you do integration testing against EF using an in-memory database like SqlLite rather than unit testing it.
Still, if you are intent on using repositories, there are many examples out there on the net, with varying styles and methods. Or you can roll your own. MS does not provide one.
In my experience, write your own repositories is redundant because EF implements this pattern already through DbSet's.
I worked with MVC3 + EF Code Fisrt in a recent project. We started implementing a generic repository following some tutorials and soon we realized that we are writing a lot of unnecessary and redundant code. Actually, the repositories were given us nothing but hiding a lot of the DbSet's functionality. Finally, we decided to remove them and work with our DbContext and DbSet's directly.
But, how about complex business logic beyond simple CRUD operations?
Well, we exposed all complex functionality like queries and multiple CRUD operations through a service layer. You can build different service classes by functionality. By example, you can write an AccountService to manage all functionality related with user accounts. Something like this:
public class AccountService {
private MyContext ctx;
public AccountService(DbContext dbContext) {
this.ctx = (MyContext)dbContext;
}
/// <summary>
/// Gets the underlying DbContext object.
/// </summary>
public DbContext DbContext {
get { return ctx; }
}
/// <summary>
/// Gets the users repository.
/// </summary>
public DbSet<User> Users {
get {return ctx.Users;}
}
public bool ValidateLogin(string username, string password) {
return ctx.Users.Any(u => u.Username == username && u.Password == password);
}
public string[] GetRolesForUser(string username) {
var qry = from u in ctx.Users
from r in u.Roles
where u.Username == username
select r.Code;
return qry.ToArray<String>();
}
public User CreateUser(string username, string password) {
if (String.IsNullOrWhiteSpace(username)) throw new ArgumentException("Invalid user name");
if (String.IsNullOrWhiteSpace(password)) throw new ArgumentException("Invalid password");
User u = new User {
Username = username.Trim().ToLower(),
Password = password.Trim().ToLower(),
Roles = new List<Role>()
};
ctx.Users.Add(u);
ctx.SaveChanges();
return u;
}
How about dependency injection?
Using this approach, the only thing we need to inject is the DbContext. The service classes has a constructor that takes a DbContext. So, when your controller constructor takes a service instance the DbContext will be injected to it.
Edit: Example code
This is an example code about how you controller could look:
public class HomeController : Controller {
private readonly AccountService accountService;
public AccountController(AccountService accountService) {
this.accountService = accountService;
}
}
And this could be the DI configuration using NInject:
private static void RegisterServices(IKernel kernel) {
kernel.Bind<MyContext>().ToSelf().InRequestScope();
kernel.Bind<DbContext>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
}
How about unit testing?
You could build specific interfaces for each service layer class and mock it where you need.
A friend of mine, Sacha Barber wrote a nice article covering some of these ideas.
Link can be found here.
RESTful WCF / EF POCO / Unit of Work / Repository / MEF: 1 of 2
EF has a base class called DbContext. You can add properties of type DbSet<TEntity>
This allows you to do something like this:
public class User {
public int Id { get; set; }
public string Name { get; set; }
}
public class DatabaseContext : DbContext {
public DbSet<User> Users { get; set; }
}
You can now use this like so:
using(var db = new DatabaseContext()) {
User jon = new User {Name = "Jon Smith"};
db.Users.Add(jon);
db.SaveChanges();
var jonById = db.Users.Single(x => x.Id == 1);
}
If you want more abstraction see this post about building a generic repository around EF Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable Just to note, this level of abstraction is not always needed. You should decide if your abblication will truly benefit from adding a generic repository over just using DbContext directly.

How to Moq a service in a controller which use unitofwork with generic repository

I am a newbie in TDD (Asp.net MVC3 environment) and trying to adopt TDD as our better better development approach.
In our production code,we have a following scenario
In web
//Autofac used to resolve Dependency
TestController(XService xSerivice,YSerivice yService)
{_xService =xService,_YService= yService}
[HTTPPost]
ActionResult Create(A1 a1)
{
_xService.XUnitOfWork.A1.add(a1)
_xService.XUnitOfwork.SaveChanges();
}
// where X, Y are different context,Concrete class, no interface implemented!
In Business Layer
Xservice(XUnitofWork) // no interface implemented!
In DAL Layer
'XUnitofWork:DataRepostory(Generic)...
{
GenericRepository<a1Entity> A1,
GenericRepository<a2Entity> A2
}
Now I realize that we should implement interface both in our BAL and Web layer.
My question is are there any way i can mock the services(XService,YService) in our controller to test some behavior (TDD) [for example save change exception occur while saving a entity via' _xService.XUnitOfwork.SaveChanges()'?
Please help.Thanks in Advance!
If you mark members (properties, methods) in your concrete class as virtual, I think you may be able to just mock those methods / properties individually. (I think the VB equivalent of virtual is Overridable..?)
Moq works by creating a new concrete implementation of something at runtime when your test runs. This is why it works so well with interfaces and abstract classes. But if there is no interface or abstract class, it needs to override a method or property.
Reply to question author's answer:
Since you are a self-proclaimed TDD newbie, I just wanted to point out that adding a parameterless constructor to a class just for the sake of making the class testable should not be an acceptable solution.
By giving your GenericRepository class a hard dependency on Entity Framework's DbSet / IDbSet, you are creating a tight coupling between your repository implementation and EF... note the using System.Data.Entity line at the top of that file.
Any time you decide to add a constructor dependency, you should seriously consider adding it as an interface or abstract class. If you need access to members of a library which you do not control (like EF's DbContext), follow Morten's answer and wrap the functionality in your own custom interface.
In the case of DbContext, this class does more than just provide you with a UnitOfWork implementation. It also provides you a way of querying out data and adding / replacing / removing items in your repository:
public interface IUnitOfWork
{
int SaveChanges();
}
public interface IQuery
{
IQueryable<TEntity> GetQueryable<TEntity>() where TEntity : class;
}
public interface ICommand : IQuery
{
void Add(object entity);
void Replace(object entity);
void Remove(object entity);
}
You can pretty easily wrap DbContext in these 3 interfaces like so:
public class MyCustomDbContext : DbContext, IUnitOfWork, ICommand
{
// DbContext already implements int SaveChanges()
public IQueryable<TEntity> GetQueryable<TEntity>() where TEntity : class
{
return this.Set<TEntity>();
}
public void Add(object entity)
{
this.Entry(entity).State = EntityState.Added;
}
public void Replace(object entity)
{
this.Entry(entity).State = EntityState.Modified;
}
public void Remove(object entity)
{
this.Entry(entity).State = EntityState.Deleted;
}
}
Note how your interfaces take no dependencies on System.Data.Entity. They use primitives and standard .NET types like object, IQueryable<T>, and int. This way, when you give your generic repository dependencies on the interfaces, you can remove the dependency on System.Data.Entity:
// using System.Data.Entity; // no need for this dependency any more
public class GenericRepository
{
private readonly ICommand _entities;
private readonly IQueryable<TEntity> _queryable;
public GenericRepository(ICommand entities)
{
this._entities = entities;
this._queryable = entities.GetQueryable<TEntity>();
}
//public GenericRepository()
//{
// no need for a parameterless constructor!
//}
}
...and your GenericRepository is now fully unit testable, since you can easily mock any of these interface methods.
Final Notes:
Also, after seeing your answer to your own question, it looks like you have CompanyRepository as a property of your UnitOfWork class. You then inject UnitOfWork as a dependency on your CompanyInformationController. This is backwards. Instead, you should be injecting the CompanyRepository (or its interface) into the controller's constructor. The UnitOfWork pattern has nothing to do with maintaining references for your known repositories. It is about tracking multiple changes made to related items so that they can all be pushed once as a single transaction. EF does this automatically, so as long as AutoFac is providing the same DbContext instance no matter whether your app requests an IQuery, ICommand, or IUnitOfWork implementation, then the only method UnitOfWork should be concerned with is SaveChanges().
thanks for your reply. The test I was trying to do was successful after spending few hours and changes my previous code.
Changes are follows:
1) Now using UnitofWork in my controller instead of a redundant service.
2) Added a parameter less constructor to the GenericRepository Class.(with out any DBContext!),because it will requied a DBContext as a parameter in Constructor,which can not be substituted by supplying a Mocked DBContext.
GenericRepository:
public class GenericRepository where TEntity : class
{
internal DbContext _context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this._context = context;
this.dbSet = context.Set<TEntity>();
}
public GenericRepository() //newly added!
{
}
...............
Complete Test
[TestMethod]
public void Index_Return_OneModel_WhenCalling()
{
//arrange
AutoMapperExtension automapper = new AutoMapperExtension();
var moqentities = new Mock<SetupEntities>();
List<CompanyInformation> list =new List<CompanyInformation>();
list.Add(new CompanyInformation{ CompanyName = "a", CompanyAddress = "aa", Id = 1});
list.Add(new CompanyInformation { CompanyName = "b", CompanyAddress = "b", Id = 2 });
var unitOfWork = new Mock<UnitOfWork>(moqentities.Object);
unitOfWork.Setup(d => d.CompanyRepository).Returns(new GenericRepository<CompanyInformation>());
unitOfWork.Setup(d => d.CompanyRepository.GetAll()).Returns(list.AsQueryable());
var controller = new CompanyInformationController(unitOfWork.Object);
//Act
var result =(ViewResult) controller.Index();
var model =(CompanyInformationViewModel) result.ViewData.Model;
//Assert
Assert.AreEqual(1, model.Id);
}
The best way is to create an interface for XService. If that is not possible for some reason (if XService is a third party class that doesn't implement an interface), then consider wrapping the functionality in a wrapperclass that does have an interface.

How to decouple repository and entities

This is a question on domain model design.
Let's say for a domain design involving users and groups, we have the following interfaces to implement:
interface IUser
{
string Name{get;}
DateTime DOB {get;}
}
interface IGroup
{
string Name {get;}
bool IsUserInGroup(IUser user); // #1
void IncludeUser(IUser user); // #2
void ExcludeUser(IUser user); // #3
}
interface IUserRepository
{
IUser Create(string name);
IUser GetByName(string name);
void Remove(IUser user);
void Save(IUser user);
}
interface IGroupRepository
{
IGroup Create(string name);
IGroup GetByName(string name);
void Remove(IGroup group);
void Save(IGroup group);
}
The tricky bit is to implement #1 #2 and #3 while keeping the entity classes (User, Group) decoupled from the repository classes (UserRepository, GroupRepository.)
Another technicality to consider is that most RMDB systems do not implement many-to-many relationships, and in practice there is always a separate table (say, UserGroupAssociation) to have records each associates a user and a group via foreign keys. I would like to hide this implementation detail from the domain interfaces and expose the equivalent logic through members #1 #2 and #3.
The effect of calling #2 and #3 should not persist until the group object in question has been saved (i.e. passed to the Save() method of the repository object)
How do you usually do it?
I don't do it. My Repository objects are tightly coupled to the root of the aggregate to which they relate, and (as kind of an aside) I don't bother making interfaces for my domain model objects unless I find I have a good reason to do so - do you have a particular reason to do this?
I've not come across any Repository examples which don't use the entity implementation type in the repository class (this one, for instance) and can't think of any real advantage of using an interface instead. Interfaces earn their keep for infrastructure components (like a Repository) by making it easier to mock out entire layers of the system when testing, you don't get the same type of advantage using interfaces for domain objects.
And to perhaps actually answer the question...
I never have a domain object access a Repository - the domain object after all is supposed to represent something in the domain in real life, and Repositories are infrastructure components that don't exist in real life, so why would a domain object know about one?
For the specific example of adding a User to a Group, I'd use a Service Layer class, and do this:
public class UserService
{
private readonly IGroupRepository _groupRepository;
private readonly IUserRepository _userRepository;
public UserService(
IGroupRepository groupRepository,
IUserRepository userRepository)
{
this._groupRepository = groupRepository;
this._userRepository = userRepository;
}
public void IncludeUserInGroup(string groupName, string userName)
{
var group = this._groupRepository.FindByName(groupName);
var user = this._userRepository.FindByName(userName);
group.IncludeUser(user);
this._userRepository.SaveChanges();
}
}
public class User
{
public void AddToGroup(Group group)
{
this.Groups.Add(group);
}
public void RemoveFromGroup(Group group)
{
this.Groups.Remove(group);
}
}
Some points to note:
To avoid lazy-loading large numbers of Users when adding a User to a Group I've moved the Group administration methods onto User - depending on how much behaviour you actually have for Group, you might even consider turning it into an enumeration rather than a class. Be aware that if you're using the Entity Framework POCO T4 Templates with FixupCollections, this will still lazy-load all the Users in a Group, but you can get around that in one way or another :)
The Service Layer class would implement a Create() method, the like of which you have on your Repositories. The Repositories would have an Add method, Find methods and a SaveChanges() method. Add would add an object created by the Service Layer to the object context.
All Repository classes would be set up to use the same underlying, request-scoped object context, so it wouldn't matter which one you call SaveChanges() on.
SaveChanges() would cause all changes which had happened to objects during that request to be saved, such as a User having a new Group's added to their Groups collection.
Finally, another good technique for decoupling entities from Repositories and other infrastructure components is Domain Events.

Resources