I'm currently working on my exam project in ASP.NET MVC 5 (C#).
My problem is one of my controllers, which is heavily relying on the authorize roles attribute to make sure people have a certain role and thereby access to the various functions in the controller. It was working fine, right until I wanted to use dependency injection through the constructor... it seems after I installed ninject for mvc3, set up the bind and made the constructor accepting the interface in the controller. That it just ignores all authorize tags? I know it's not syntax errors because nothing is different in the controller, except the new constructor. This seems to have no effect on the account controller though so I have to presume Ninject is messing things up.
Everyone can do everything they want and run all methods in the controller since I set it up for ninject and I simply don't get it?
Can anyone help or know of this issue and any steps to take to fix it?
I have to turn in the project monday so I was hoping some guru could enlighten me relatively fast on this issue. A google search tells me Ninject doesn't work with the attribute is that true? If it is I'm pretty screwed.
Well I basically added this to the NinjectWebCommon's "RegisterServices" method:
kernel.Bind<IChildRepository>().To<ChildRepository>();
(I'm making a site for an institution that watches kids after school etc. the childcontroller controls the management of "children" created in the system).
private readonly IChildRepository _childRepository;
public ChildController(IChildRepository childRepository)
{
_childRepository = childRepository;
}
This is my repository class:
public class ChildRepository : IChildRepository
{
ChildContext context = new ChildContext();
public IQueryable<Child> All
{
get { return context.Children; }
}
public IQueryable<Child> AllIncluding(params Expression<Func<Child, object>>[] includeProperties)
{
IQueryable<Child> query = context.Children;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public Child Find(int id)
{
return context.Children.Find(id);
}
public void InsertOrUpdate(Child child)
{
if (child.ChildId == default(int))
{
context.Children.Add(child);
}
else
{
context.Entry(child).State = System.Data.Entity.EntityState.Modified;
}
}
public void Delete(int id)
{
var child = context.Children.Find(id);
context.Children.Remove(child);
}
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
And my repo interface:
public interface IChildRepository : IDisposable
{
IQueryable<Child> All { get; }
IQueryable<Child> AllIncluding(params Expression<Func<Child, object>>[] includeProperties);
Child Find(int id);
void InsertOrUpdate(Child child);
void Delete(int id);
void Save();
}
This is the index method in the controller method to show you how I'm using authorize:
[Authorize(Roles = "Admin, CanEdit")]
public ActionResult Index()
{
return View(_childRepository.All.ToList());
}
How it works now? You can access the childcontroller views and all the other methods besides index without even being logged into the system?
I found the solution to the problem by googling, apparently adding this line to the registerservices method solves the entire issue.
kernel.Bind<IFilterProvider>().To<FilterAttributeFilterProvider>();
Got it from this guy which I love right now:
http://pieterderycke.wordpress.com/2012/03/01/using-asp-net-filters-with-the-ninject-depencency-resolver/
Thought I would answer the question myself so if others run into the same issue they can make it work!
Related
Question:
Why does passing a list from a protected internal class to an API method and then back to my UI take 4 seconds when direct data access in Entity takes .4? Is it due to the actual passing of the list through these methods?
Background:
I wish to create an "API" layer that sits between my data access layer using Entity Framework and my UI layer. The idea is to limit access to the CRUD operations and force everything through the API however I'm noticing terrible performance.
When I use my class structure here, the get method in this case takes 4 seconds to run:
public class API
{
DataAccessClass _dataAccess = new DataAccessClass();
public List<Items> GetById(int id)
{
return _dataAccess.Get(id);
}
protected internal class DataAccessClass
{
protected internal List<Items> GET(int id)
{
using (var context = dbcontext)
{
return context.GetItems();
}
}
protected internal List<Items> GET(long id)
{
using (var context = dbcontext)
{
return context.GetItems();
}
}
}
}
However when I use my dbcontext directly in code (which I want to prevent), it runs in .4 seconds using the same code found in the protected class above:
using (var context = dbcontext)
{
return context.GetItems();
}
EDIT:
When I exclude the data access portion of the API which is the protected internal portion, and run the using statement in the API directly (just cutting out the protected internal portion) then I get the acceptable .4 seconds.
To solve my performance issue, I removed overloads from the GET class above.
My performance issues from the original question where resolved by changing method names on two of my get methods (one that took an int and one long). Not sure why these overloads causes issues but by removing the overloads and specifying names directly, my issue with performance was resolved.
My working class looks like:
public class API
{
DataAccessClass _dataAccess = new DataAccessClass();
public List<Items> GetById(int id)
{
return _dataAccess.Get(id);
}
protected internal class DataAccessClass
{
protected internal List<Items> GetByInt(int id)
{
using (var context = dbcontext)
{
return context.GetItems();
}
}
protected internal List<Items> GetByLong(long id)
{
using (var context = dbcontext)
{
return context.GetItems();
}
}
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
If you don't care about the code I wrote and just want to have a discussion about abstracting existing abstractions... skip to the last 3 paragraphs.
I was introduced to the idea of Repositories and the Unit Of Work on top of Entity Framework via a Pluralsight lesson I was watching. I also stubmled upon Microsoft's own page detailing this process: http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
So I decided to try it out. I set out to write my own Unit Of Work class with generic Repositories on top of Entity Framework, making absolutely everything along the way utilize interfaces so I could inject my own mocks for testing.
First things first, for this exercise I chose to make a simple Blog application.
So I started with the DbContext. Gotta make sure I use an interface!
public interface ISimpleBlogContext : IDisposable
{
IDbSet<Blog> Blogs { get; }
IDbSet<Post> Posts { get; }
void SaveChanges();
IDbSet<T> Set<T>() where T : class;
DbEntityEntry Entry<T>(T entity) where T : class;
}
I'm sure everybody knows what the IDbSets are for, but the SaveChanges, Set, and Entry methods might look a bit out of place. Don't worry, we'll get to those later.
So now I hooked up my interface into an actual concrete DbContext :
public class SimpleBlogContext : DbContext, ISimpleBlogContext
{
public SimpleBlogContext() {
Database.SetInitializer<SimpleBlogContext>(new DropCreateDatabaseAlways<SimpleBlogContext>());
}
public IDbSet<Blog> Blogs { get; set; }
public IDbSet<Post> Posts { get; set; }
public DbEntityEntry Entry<T>(T entity) where T : class
{
return Entry<T>(entity);
}
void ISimpleBlogContext.SaveChanges()
{
SaveChanges();
}
IDbSet<T> ISimpleBlogContext.Set<T>()
{
return Set<T>();
}
The database initializer is just ensuring that for this test application the database is dropped and recreated each time I run the app. This was just an exercise and not a real app after all. You can see the SaveChanges, Set, and Entry methods implemented here, and they're all nothing more than wrappers for the DbContext methods of the same name.
So now on to the repositories...
I wasn't going to re-write virtually the same repository code for every entity I might add to my application (although in this case I'll only wind up using one repository), so I made a generic repository. Don't skip the interface!
public interface IGenericRepository<T>
where T : class
{
IEnumerable<T> GetAll();
T GetById(object id);
IEnumerable<T> GetByExpression(Expression<Func<T, bool>> expression);
void Add(T entity);
void Delete(T entity);
void Update(T entity);
}
and the concrete version... (notice I'm using my ISimpleBlogContext here instead of a concrete DbContext class because I want to be able to test all the things. Also, now you know why I had to write those Set, Entry, and SaveChanges methods in my ISimpleBlogContext interface)
public class GenericRepository<T> : IGenericRepository<T>
where T : class
{
public GenericRepository(ISimpleBlogContext context)
{
this.context = context;
}
private ISimpleBlogContext context;
public void Add(T entity)
{
context.Set<T>().Add(entity);
}
public void Delete(T entity)
{
context.Set<T>().Remove(entity);
}
public IEnumerable<T> GetAll()
{
return context.Set<T>().ToList<T>();
}
public IEnumerable<T> GetByExpression(Expression<Func<T, bool>> expression)
{
return context.Set<T>().Where<T>(expression).ToList<T>();
}
public T GetById(object id)
{
return context.Set<T>().Find(id);
}
public void Update(T entity)
{
context.Entry(entity).State = EntityState.Modified;
}
}
And now finally, the Unit Of Work class
public class UnitOfWork : IDisposable
{
public void Dispose()
{
if (context != null)
{
context.Dispose();
context = null;
}
}
public UnitOfWork()
{
context = new SimpleBlogContext();
}
public UnitOfWork(ISimpleBlogContext context)
{
this.context = context;
}
private ISimpleBlogContext context;
public GenericRepository<TEntity> GetRepository<TEntity>() where TEntity : class
{
return new GenericRepository<TEntity>(context);
}
public void Save()
{
context.SaveChanges();
}
}
I'm still allowing an ISimpleBlogContext to be passed in via the overloaded constructor, but the default constructor is where we finally get our concrete SimpleBlogContext DbContext from.
So now I just have to test all this. So I wrote a simple Console application which does nothing more than generate a couple of fake blogs with a couple of fake posts and save them using the Unit Of Work class. Then it loops the blogs and posts and prints them out so I can verify that they were actually saved to the database.
P.S. Jake is my dog in case you're wondering about the barking...
class Program
{
static void Main(string[] args)
{
UnitOfWork unitOfWork = new UnitOfWork();
GenericRepository<Blog> blogRepository = unitOfWork.GetRepository<Blog>();
Blog paulsBlog = new Blog()
{
Author = "Paul",
Posts = new List<Post>()
{
new Post()
{
Title = "My First Post",
Body = "This is my first post"
},
new Post()
{
Title = "My Second Post",
Body = "This is my second post"
}
}
};
Blog jakesBlog = new Blog()
{
Author = "Jake",
Posts = new List<Post>()
{
new Post()
{
Title = "Dog thoughts",
Body = "Bark bark bark"
},
new Post()
{
Title = "I like barking",
Body = "Bark bark bark"
}
}
};
blogRepository.Add(paulsBlog);
blogRepository.Add(jakesBlog);
unitOfWork.Save();
List<Blog> blogs = blogRepository.GetAll() as List<Blog>;
foreach (Blog blog in blogs)
{
System.Console.WriteLine("ID: {0}, Author: {1}\n", blog.Id, blog.Author);
if (blog.Posts != null && blog.Posts.Count > 0)
{
foreach (Post post in blog.Posts)
{
System.Console.WriteLine("Posted at: {0}, Title: {1}, Body: {2}", post.PostTime, post.Title, post.Body);
}
}
else
{
System.Console.WriteLine("No posts");
}
System.Console.WriteLine("\n");
}
}
}
It works. Yay!
My question, however, is simply... what did I gain exactly by doing any of this?
Isn't DbContext already a Unit Of Work and DbSet is already a repository? It seems all I did was write a really elaborate wrapper for both of those things with no added functionality at all. You might say that it's more test-friendly since everything is using interfaces, but with mocking frameworks like Moq it's already possible to mock a DbSets and DbContexts. My repositories are generic so there is literally zero functionality that is specific to business logic. The Unit Of Work class is just a wrapper for DbContext and the generic Repositories are just wrappers for DbSet.
Can somebody explain to me why anybody would do this? I watched a ~4 hour Pluralsight lesson on this, plus went through all the trouble of actually doing it myself, and I still don't get it.
I did the same thin recently and I believe you gain the flexibility of testing your code without requiring actual access to a SQL database.
I'm using ASP 5, MVC 6, and Entity Framework 7 to create a small website (foreseeably less than 100 registered users and 10,000 monthly visitors). I'm a rookie programmer with under 1000 hours of combined experience and research.
I've got a lot of questions at the bottom, but in general I'd just like to be sure I understand the repository pattern and why it could be beneficial to me. Right now I'm only using it because I read 'it's good idea' from multiple sources, and because it seems to make sense for organizational purposes.
After I read about the Repository Pattern. I took some ideas from these sources:
Microsoft, Code Guru, DotNetCurry
I created a generic interface IRepository:
interface IRepository<TEntity,in TPKey> where TEntity : class
{
IEnumerable<TEntity> GetAll();
TEntity Get(TPKey id);
void Insert(TEntity ent);
void Update(TEntity ent);
void Delete(TEntity ent);
}
Then I created a specific Repository for one of my entities:
public class CollegeRepository : IRepository<Models.College, int>
{
private ApplicationDbContext _context = null;
public CollegeRepository()
{
_context = new ApplicationDbContext();
}
public CollegeRepository(ApplicationDbContext context)
{
this._context = context;
}
public College Get(int id)
{
return _context.Colleges.Where(c => c.CollegeID == id).FirstOrDefault();
}
public IEnumerable<College> GetAll()
{
return _context.Colleges.ToList();
}
public void Insert(College college)
{
_context.Colleges.Add(college);
}
public void Update(College college)
{
_context.Update(college);
}
public void Delete(College college)
{
_context.Colleges.Remove(college);
}
Inside of my CollegesController I originally did something like this:
// POST: Schools/Edit/5
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public IActionResult Edit(College school, IFormFile logo)
{
if (ModelState.IsValid)
{
if (logo != null)
{
byte[] imgBytes = new byte[logo.Length];
logo.OpenReadStream().Read(imgBytes, 0, (int)logo.Length);
school.Logo = imgBytes;
_context.Update(school);
}
else
{
// Mark the logo as unmodified so the data is not lost.
_context.Update(school).Property(s => s.Logo).IsModified = false;
}
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(school);
}
Then changed to this:
// POST: Schools/Edit/5
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public IActionResult Edit(College school, IFormFile logo)
{
if (ModelState.IsValid)
{
collegeRepo.Update(school, logo);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(school);
}
And modified the specific repository to add an Update overload:
public class CollegeRepository : IRepository<Models.College, int>
{
public void Update(College college)
{
_context.Update(college);
}
public void Update(College college, IFormFile logo)
{
if (logo != null)
{
byte[] imgBytes = new byte[logo.Length];
logo.OpenReadStream().Read(imgBytes, 0, (int)logo.Length);
college.Logo = imgBytes;
_context.Update(college);
}
else
{
// Mark the logo as unmodified so the data is not lost.
_context.Update(college).Property(s => s.Logo).IsModified = false;
}
}
}
It seems I have successfully separated my logic from my controller. Is this the idea behind the repository pattern? Have I used it successfully in this example? To what degree am I unsuccessful?
I was reading, after I did all this, that the repository pattern is not all that useful for projects which will only use (and may only ever use) 1 data source (like mine), but that there should always be some sort of Unit of Work class to keep logic out of controllers (I vaguely understand what it means to have a unit of work, but answers that touch on this would be appreciated as well).
I've also read that the repository pattern is helpful for reducing duplicate code. I can't see far enough ahead, with my inexperienced eyes, to think that I might use any of my controller code again. What are some common MVC scenarios where you've seen (could see) code duplication occur without the repository pattern?
I've just started programming in .NET and I'm having some problems with implementing dependency injection (using Ninject).
I'm creating some sort of catering application where user can browse towns, in towns browse restaurants and in restaurants browse food.
I'm using UnitOfWork and repository pattern where for example I access town by id like this:
_unitOfWork.TownRepository.GetByID(id);
Now I started implementing services into application and I have encountered need for dependency injection.
I have created ITownService, IRestaurantService and IFoodService (since I've TownRepository, RestaurantRepository and FoodRepository in my UnitOfWork).
Sample look of TownService:
public class TownService : ITownService
{
// initialize UnitOfWork
private IUnitOfWork _unitOfWork;
public TownService()
: this(new UnitOfWork())
{
}
public TownService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public Town GetByID(object id)
{
return _unitOfWork.TownRepository.GetByID(id);
}
public IEnumerable<Town> GetAll()
{
return _unitOfWork.TownRepository.Get();
}
public bool Insert(Town town)
{
// validation logic
if (!ValidateTown(town))
return false;
try
{
_unitOfWork.TownRepository.Insert(town);
_unitOfWork.Save();
}
catch
{
return false;
}
return true;
}
public bool Delete(object id)
{
try
{
_unitOfWork.TownRepository.Delete(id);
_unitOfWork.Save();
}
catch
{
return false;
}
return true;
}
public bool Update(Town townToUpdate)
{
// validation logic
if (!ValidateTown(townToUpdate))
return false;
try
{
_unitOfWork.TownRepository.Update(townToUpdate);
_unitOfWork.Save();
}
catch
{
return false;
}
return true;
}
}
I haven't implemented FoodService and RestaurantService yet, but they should be similar with of course some additinal methods exepct this that I have. For example in RestaurantService I might have public Restaurant GetRestaurantsInTown(Town town){} or something like that.
I hope that you got the feel of application a bit. Now lets back to Ninject.
In my TownController I would have something like this:
public class TownController : Controller
{
private ITownService _townService;
public TownController(ITownService townService)
{
_townService = townService;
}
}
Similar would be for RestaurantController and FoodController of course just constructor injecting.
How do I use Ninject in such example? Do I need some global IService and not ITownService, IRestaurantService and IFoodService which I'd inherid in TownService, RestaurantService and FoodService or is it okay like this?
When binding what do I need to bind?
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
kernel.Bind<ITownService>().To<TownService>();
kernel.Bind<IRestaurantService>().To<RestaurantService>();
kernel.Bind<IFoodService>().To<TownService>();
Something like this?
In short - what I need for adding dependency injection with Ninject?
I'm really having problems with this and would need help.
Thanks a lot in forward.
From the package manager console run this command:
Install-package Ninject.MVC3
This will add a class to App_Start/NinjectWebCommon.cs
If you look near the bottom there is a RegisterServices method.
You simply add the code from your question there i.e.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
kernel.Bind<ITownService>().To<TownService>();
kernel.Bind<IRestaurantService>().To<RestaurantService>();
kernel.Bind<IFoodService>().To<TownService>();
}
I am developing a multi-tenant web application using MVC4 and EF5. I previously asked this question regarding filtering my DbContext: Is it bad practice to filter by ID within the repository pattern.
Apparently, my approach was sound, but it was suggested that rather than handling all filtering in that single repository, I provide a context already filtered to tenant level using 'a repository or DBContextWrapper class that would feed your [my] normal repository'.
Unfortunately I am no MVC expert, so I started implementing this as best I could, but upon researching filtering in EF for other multi-tenant applications I found a question for a very similar case Multi-tenancy web application with filtered dbContext, though completely failed to understand the answer to it.
In my application, the CompanyID is a property of the User class, so should be taken directly from the authenticated user. Eg:
int CompanyID = db.Users.Single(u => u.Email == User.Identity.Name).CompanyID;
My current approach does appear to work, however I'm pretty sure I have gone about it the wrong way and/or have done it inefficiently based on what I've seen in other Questions about doing the same sort of thing. In another question Solutions for a simple multi tenant web application with entity framework reflection is used to do this, but I'm not able to work out whether it would apply in my case, or even how to use it.
I would be extremely appreciative if anyone can explain the best way of going about this, and the pros/cons of differing ways. Thanks :)
My current implementation is as follows:
DB
One database, multiple tenants.
All tables link back to Company table one way or another, although not all have a CompanyID field.
TestController.cs
public class TestController : Controller
{
private BookingSystemEntities db = new BookingSystemEntities();
public ActionResult Index()
{
var user = db.Users.Single(u => u.Email == User.Identity.Name);
IBookingSystemRepository rep = new BookingSystemRepository(db, user);
return View(rep.GetAppointments(false));
}
}
BookingSystemRepository.cs
public class BookingSystemRepository : IBookingSystemRepository
{
private CompanyBookingSystemRepository db;
public BookingSystemRepository(BookingSystemEntities context, User user)
{
this.db = new CompanyBookingSystemRepository(context, user);
}
public IEnumerable<Appointment> GetAppointments()
{ return GetAppointments(false); }
public IEnumerable<Appointment> GetAppointments(bool includeDeleted)
{
return includeDeleted
? db.Appointments
: db.Appointments.Where(a => a.Deleted.HasValue);
}
public IEnumerable<Client> GetClients()
{ return GetClients(false); }
public IEnumerable<Client> GetClients(bool includeDeleted)
{
return includeDeleted
? db.Clients
: db.Clients.Where(c => c.Deleted.HasValue);
}
public void Save()
{
db.SaveChanges();
}
public void Dispose()
{
if (db != null)
db.Dispose();
}
}
CompanyBookingSystemRepository.cs
public class CompanyBookingSystemRepository
{
private BookingSystemEntities db;
private User User;
public IEnumerable<Appointment> Appointments { get { return db.Appointments.Where(a => a.User.CompanyID == User.CompanyID).AsEnumerable<Appointment>(); } }
public IEnumerable<Client> Clients { get { return db.Clients.Where(a => a.CompanyID == User.CompanyID).AsEnumerable<Client>(); } }
public CompanyBookingSystemRepository(BookingSystemEntities context, User user)
{
db = context;
this.User = user;
}
public void SaveChanges()
{
db.SaveChanges();
}
public void Dispose()
{
if (db != null)
db.Dispose();
}
}
I like your approach better than some of the other examples you've provided. Filtering based on the logged-in user should be the most effective way to make sure you're filtering your data appropriately assuming each tenant runs off the same codebase and domain. (If not, you could utilize those to filter as well.)
If you're concerned about database performance with filtering tables that don't have a CompanyID you can purposely denormalize your database to include that field in those tables.
The reflection approach you cited, although elegant, seems overly complicated and like a lot more overhead than including the CompanyID in your db call (especially since the db call is happening in both instances).
EDIT (after comment):
As for the rest of it, you seem to have written a lot of excess code that's not really necessary (at least not within the example cited above). I don't necessarily understand why you're distinguishing between a BookingSystemRepository and a CompanyBookingSystemRepository since from your code it seems like the former exists only to pass calls through to the latter, which just filters results using the UserID (is there ever a situation where you wouldn't filter those results?).
You could eliminate both of those classes (and the issue you cite in your comment) entirely by just changing your method to:
public class TestController : Controller
{
private BookingSystemEntities db = new BookingSystemEntities();
public ActionResult Index()
{
var user = db.Users.Single(u => u.Email == User.Identity.Name);
var appointments = db.Appointments.Where(a => a.User.CompanyID == user.CompanyID).AsEnumerable();
return View(appointments);
}
public override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
From there, if you're worried about performance, you really should be doing all your filtering within the DB and then only call those procedures to return your data.