I'm working on an ASP.net MVC application and I have a question about using constructors for my controllers.
I'm using Entity Framework and linq to Entities for all of my data transactions. I need to access my Entity model for nearly all of my controller actions. When I first started writing the app I was creating an entity object at the beginning of each Action method, performing whatever work I needed to and then returning my result.
I realized that I was creating the same object over and over for each action method so I created a private member variable for the Entity object and started instantiating it in the constructor for each controller. Now each method only references that private member variable to do its work.
I'm still questioning myself on which way is right. I'm wondering A.) which method is most appropriate? B.) in the constructor method, how long are those objects living? C.) are there performance/integrity issues with the constructor method?
You are asking the right questions.
A. It is definitely not appropriate to create this dependencies inside each action method. One of the main features of MVC is the ability to separate concerns. By loading up your controller with these dependencies, you are making the controller for thick. These should be injected into the controller. There are various options for dependency injection (DI). Generally these types of objects can be either injected into the constructor or into a property. My preference is constructor injection.
B. The lifetime of these objects will be determined by the garbage collector. GC is not deterministic. So if you have objects that have connections to resource constrained services (database connections) then you may need to be sure you close those connections your self (instead of relying on dispose). Many times the 'lifetime' concerns are separated out into an inversion of control (IOC) container. There are many out there. My preference is Ninject.
C. The instantiation costs are probably minimal. The database transactions cost are where you probably want to focus your attention. There is a concept called 'unit of work' you may want to look into. Essentially, a database can handle transactions larger than just one save/update operation. Increasing the transaction size can lead to better db performance.
Hope that gets you started.
RCravens has some excellent insights. I'd like to show how you can implement his suggestions.
It would be good to start by defining an interface for the data access class to implement:
public interface IPostRepository
{
IEnumerable<Post> GetMostRecentPosts(int blogId);
}
Then implement a data class. Entity Framework contexts are cheap to build, and you can get inconsistent behavior when you don't dispose of them, so I find it's usually better to pull the data you want into memory, and then dispose the context.
public class PostRepository : IPostRepository
{
public IEnumerable<Post> GetMostRecentPosts(int blogId)
{
// A using statement makes sure the context is disposed quickly.
using(var context = new BlogContext())
{
return context.Posts
.Where(p => p.UserId == userId)
.OrderByDescending(p => p.TimeStamp)
.Take(10)
// ToList ensures the values are in memory before disposing the context
.ToList();
}
}
}
Now your controller can accept one of these repositories as a constructor argument:
public class BlogController : Controller
{
private IPostRepository _postRepository;
public BlogController(IPostRepository postRepository)
{
_postRepository = postRepository;
}
public ActionResult Index(int blogId)
{
var posts = _postRepository.GetMostRecentPosts(blogId);
var model = new PostsModel { Posts = posts };
if(!posts.Any()) {model.Message = "This blog doesn't have any posts yet";}
return View("Posts", model);
}
}
MVC allows you to use your own Controller Factory in lieu of the default, so you can specify that your IoC framework like Ninject decides how Controllers are created. You can set up your injection framework to know that when you ask for an IPostRepository it should create a PostRepository object.
One big advantage of this approach is that it makes your controllers unit-testable. For example, if you want to make sure that your model gets a Message when there are no posts, you can use a mocking framework like Moq to set up a scenario where your repository returns no posts:
var repositoryMock = new Mock<IPostRepository>();
repositoryMock.Setup(r => r.GetMostRecentPosts(1))
.Returns(Enumerable.Empty<Post>());
var controller = new BlogController(repositoryMock.Object);
var result = (ViewResult)controller.Index(1);
Assert.IsFalse(string.IsNullOrEmpty(result.Model.Message));
This makes it easy to test the specific behavior you're expecting from your controller actions, without needing to set up your database or anything special like that. Unit tests like this are easy to write, deterministic (their pass/fail status is based on the code, not the database contents), and fast (you can often run a thousand of these in a second).
Related
I want to ask a simple question about MVC controllers. I have googled a lot about controllers for "different controllers for each basic table", it cleared a lot of things but i have one question that i couldn't find answer for.
My question is that if i create controller for each basic table, lets say i have 10 basic tables that would create 10 controllers. So does lots of controller slows the application performance?
- In case, when going from view to controller.
- In case, when going from controller to another controller.
I am new so kindly be calm :)
Usually, one request is processed by one controller. And if it (cotroller) is small and have a few dependencies - it's quick. When you have one huge controller with many dependencies of other classes that have their own dependencies and so on... it could be a problem.
The Short Answer
No.
The Long Answer
The number of controllers doesn't have as much of a performance impact as how expensive each controller instance is to create.
The amount of overhead you might get for the number of controllers is negligible. Although the MVC framework uses .NET Reflection to identify the current controller type, it is optimized to look in the <Project Name>.Controllers namespace first. But this list is cached in a file, so after the first hit the performance is pretty good.
Where you might run into performance problems is when you do heavy processing within the controller constructor. The framework creates a controller instance for every request, so you should make it as cheap as possible to create a controller instance. If you follow a DI-centric (dependency injection) approach even if you are not actually using DI in your project, you will be able to keep the cost of creating a controller instance to a bare minimum.
What this means in plain English is - inject your dependencies into the constructor when the controller is created only. Don't actually do any processing in the constructor, defer that for the actual Action method call.
public interface IHeavyProcessingService
{
IProcessingResult DoSomethingExpensive();
}
public class HeavyProcessingService : IHeavyProcessingService
{
public HeavyProcessingService() {
}
public IProcessingResult DoSomethingExpensive() {
// Lots of heavy processing
System.Threading.Thread.Sleep(300);
}
}
public class HomeController
{
private readonly IHeavyProcessingService heavyProcessingService;
// The constructor does no heavy processing. It is deferred until after
// the instance is created by HeavyProcessingService.
// The only thing happening here is assignment of dependencies.
public HomeController(IHeavyProcessingService heavyProcessingService) {
this.heavyProcessingService = heavyProcessingService
?? throw new ArgumentNullException(nameof(heavyProcessingService));
};
public ActionResult Index()
{
var result = this.heavyProcessingService.DoSomethingExpensive();
// Do something with the result of the heavy processing
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Contact()
{
return View();
}
}
See this answer for more information.
If you do actually use a DI container in your application, you can improve performance even more by choosing the correct lifestyle of each dependency. If you can share the same dependency instance across multiple controller instances (singleton lifestyle), it makes the controller instance even cheaper to create.
What Backs said isn't necessarily true, either. The number of dependencies doesn't matter so much as how expensive those dependencies are to create. As long as the constructors are kept light and simple and the correct lifestyle is used for each dependency, performance won't be an issue regardless of the number of dependencies a controller has. That said, the controller shouldn't have more than about 5 direct dependencies - after that, you should refactor to aggregate services, making the dependency hierarchy more like an upside down pyramid rather than a flat set that are all injected into the controller.
It depends on the number of calls to controller.If you make frequent call to a controller for 2 to 3 table so it may get slow.Instead group that 3 table in one controller and call that.If your application needs to work in individual table than its fine,You will get response quiker.But if your application needs content from 2 to 3 tables than you have to call that 3 controller.So here the better way is to group that in one controller.
Hope you got the point
If you create a WebAPI/MVC project in say Visual Studio 2013, add Model (and DbContext class), and a Controller for this model as outlined here-
http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-2,
it creates a controller that declares the DbContext as a member variable, which is according to many stackoverflow answers/online arcticles, is a bad idea- like this one
https://stackoverflow.com/a/10588594
The controller methods generated by Visual Studio-
// GET: api/Authors
public IQueryable<Author> GetAuthors()
{
return db.Authors;
}
Will not work if you use the recommended per request lifetime -
// GET: api/Authors
public IQueryable<Author> GetAuthors()
{
DbSet<Author> authors = null;
using(MyContext db = new MyContext) {
authors = db.Authors;
}
return authors;
}
Because the context is out of scope by the time the result is iterated over and you get an object disposed exception.
So, what's the correct way and if it is the "using" per request method, why does the VS template use the member variable method?
The reason is because it's a simple starting point.
It's easy to understand and easy to get started using ASP.NET MVC.
There's nothing really wrong with having a DbContext as a member variable that is created at a controller level, though it's probably not ideal. As an application becomes more complex, it just doesn't fit very well.
[ ... ] according to many stackoverflow answers/online arcticles, is a bad idea
I didn't get that from the answer that you linked at all.
Steven explains that a single DbContext (i.e. global) or a context per thread is bad.
Will not work if you use the recommended per request lifetime
That isn't a per-request lifetime. That's almost like a unit-of-work pattern, but you aren't doing anything with it.
The fix for what you're trying to do there would be
// GET: api/Authors
public IEnumerable<Author> GetAuthors()
{
IEnumerable<Author> authors = null;
using(MyContext db = new MyContext())
{
authors = db.Authors.ToList();
}
return authors;
}
In my opinion, the correct way of dealing with this is to use a per-web-request lifestyle for the DbContext with an IoC Container.
Showing a full example here is probably a bit lengthy and outside the scope of the question.
I am developing an MVC app to serve multiple domains - each is a branch of a larger company.
A LocalBranch class stores details such as phone, address, email, location coordinates etc.
I want to create a single instance of this class per http request and have it available throughout the application - from within controllers, views, some helper classes and other code.
Is there a recommended way of doing this?
Right now I have it as a property on a BaseController and use ViewBagto pass it to views. But I would prefer it strongly typed in Views if possible.
I don't want to put it in an application variable, because we need to serve different values to different domains.
I would rather avoid a session variable if possible because we might scale up to use multiple servers in the future, and I've heard this doesn't play well with sessions.
Please feel free to update tags / title if you think there is a clearer way of expressing what I'm after. Thank you.
The best way to maintain your state in a web application per request is simply use the HttpContext class.
You need to store your state(LocalBranch) as an Item in the HttpContext:
HttpContext.Current.Items.Add("LocalBranch", GetLocalBranch());
You can fetch the Item all across your application like this:
LocalBranch branch = HttpContext.Current.Items["LocalBranch"] as LocalBranch;
The Items property is simply a key value Dictionary. The value is an object. You will have to check for nulls and this is really similar to the Session object you know. The main difference is the scope. The HttpContext is a dot net object that has a lifetime of an http request.
Now using the HttpContext the way I've shown you is the simplest way to do it.
You can go two steps forward and use a framework called Unity and add a lifetime to your objects.
Unity does much more and the lifetime management is just one gem.
You can create a custom HttpContext lifetime that generates objects per request. Something like this.
And them all you need to do is:
1.Register you LocalBranch class with the HttpContext lifetime.
2.Add a static Current property which will use the Unity container and resolve the correct instance of LocalBranch.
3.Use it something like this: LocalBranch.Current
BTW, you can use Unity's dependency injection for injecting objects into controllers and other modules. That's a better practice then just using the static Current property.
You kind of have two questions here. The first is "How do I create a single instance of this class per HttpRequest?" The second is "How do I make this available to strongly typed views?"
The first has pretty much been answered by #amir-popovich to use dependency injection. However, FWIW I would probably use Ninject instead of Unity (just preference, really) and I would probably implement it differently. I would not use HttpContext, and simply build a service (which is instanciated using Ninject's OnePerHttpRequest Module, passing the domain as an argument to get the proper values).
Then, in order to add these LocalBranch values to your strongly typed View Model, you can first create a base view model which holds this type:
public class BaseViewModel
{
public LocalBranch Branch {get;set;}
}
Then, make all of your current view models inherit this base type
public MyViewModel : BaseViewModel
{
public string SomeValue {get;set;}
}
Then in your controller, it is easy enough to add these values from the service you created from the first step
public ActionResult SomeAction()
{
var vm = new MyViewModel();
vm.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
//do other stuff
return View(vm);
}
However, that gets pretty tedious to add that to each controller action, so you can instead create a Result Filter to add it for you:
public class LocalBranchResultFilter : FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
//This method gets invoked before the ActionResult is executed.
filterContext.Controller.ViewData.Model.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
}
}
Now, you can just decorate your Controller and/or Actions with the filter (you could even set it in the Global Filters if you want).
You can embed the child actions into your layout or a view. You can even cache its output so you don't keep re-querying the database.
controller
[ChildActionOnly]
[OutputCache(Duration=500, VaryByParam="*")]
public ActionResult Info()
{
var localBranch = db.GetLocalBranch();
return PartialView("_Info", localBranch);
}
_Info view
This bit will get inserted into your other views
#model LocalBranch
<span>#Model.address</span>
<span>#Model.phone</span>
Use in _Layout or other view
<p>lorem ipsum...</p>
#Html.Action("Info")
I'm developing an application using asp.net mvc, NHibernate and DDD. I have a service layer that are used by controllers of my application. Everything are using Unity to inject dependencies (ISessionFactory in repositories, repositories in services and services in controllers) and works fine.
But, it's very common I need a method in service to get only object in my repository, like this (in service class):
public class ProductService {
private readonly IUnitOfWork _uow;
private readonly IProductRepository _productRepository;
public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository) {
this._uow = unitOfWork;
this._productRepository = productRepository;
}
/* this method should be exists in DDD ??? It's very common */
public Domain.Product Get(long key) {
return _productRepository.Get(key);
}
/* other common method... is correct by DDD ? */
public bool Delete(long key) {
usign (var tx = _uow.BeginTransaction()) {
try
{
_productRepository.Delete(key);
tx.Commit();
return true;
} catch {
tx.RollBack();
return false;
}
}
}
/* ... others methods ... */
}
This code is correct by DDD ? For each Service class I have a Repository, and for each service class need I do a method "Get" for an entity ?
Thanks guys
Cheers
Your ProductService doesn't look like it followed Domain-Driven Design principles. If I understand it correctly, it is a part of Application layer between Presentation and Domain. If so, the methods on ProductService should have business meaning with regard to products.
Let's talk about deleting products. Is it as simple as executing delete on the database (NHibernate, or whatever?) I think it is not. What about orders which reference the to-be-deleted product? And so on and so forth. Btw, Udi Dahan wrote a great article on deleting entities.
Bottom line is, if your application is so simple that services do really replicate your repositories and contain only CRUD operations, you probably shouldn't do DDD, throw away your repositories and let services operate on entities (which would be simple data containers in that case).
On the other hand, if there is a complicated behavior (like the one with handling 'deleted' products), there is a point in going DDD path and I strongly advocate doing so.
PS. Despite which approach (DDD or not) you will eventually take I would encourage you to use some Aspect Oriented Programming to handle transaction and exception related stuff. You would end up with way to many methods such as DeleteProduct with same TX and exception handling code.
That looks correct from my perspective. I really didn't like repeating service and repository method names over and over in my asp.net MVC project, so I went for a generic repository approach/pattern. This means that I really only need one or two Get() methods in my repository to retrieve my objects. This is possible for me because I am using Entity Framework and I just have my repository's get() method return a IQueryable. Then I can just do the following:
Product product = from p in _productRepository.Get() where p.Id == Id select p;
You can probably replicate this in NHibernate with linq -> NHibernate.
Edit: This works for DDD because this still allows me to interchange my DAL/repositories as long as the data library I am using (Nhibernate, EF, etc..) supports IQueryable.
I am not sure how to do a generic repository without IQueryable, but you might be able to use delegates/lambda functions to incorporate it.
Edit2: And just in case I didn't answer your question correctly, if you are asking if you are supposed to call your repository's Get() method from the service then yes, that is the correct DDD design as well. The reason is that the service layer is supposed to handle all your business logic, so it decides exactly how and what data to retrieve (for example, do you want it in alphabetical order, unordered, etc...). It also means that it can perform validation after loading if needed or validation before deleting and/or saving.
This means that the service layer doesn't care exactly how that data is stored and retrieved, it only decides what data is stored and retrieved. It then calls on the repository to handle the request correctly and retrieve/store the data in the way the service layer tells it to. Thus you have correct separation of concerns.
I'm trying to think of a good way to clean up my controllers to make them more testable without having to rely on a constant database connection. I thought I had a decent start by abstracting away my object context with an IObjectContext. This works well for the context, but my next problem is that I have a generic repository that I use in a number of action methods throughout my project (see code below).
In addition to the default constructor, my controller consists of an overload, which accepts an IObjectContext (simple dependency injection). In my unit tests, I can easily mock the IObjectContext. My issue is dealing with my generic repository in various action methods. I could add a number of additional constructor overloads to the controller, but I'm afraid this would get messy, really quickly. Short of doing that, however, I simply haven't been able to think of a clean way to improve testability so that I don't have to rely on a database connection.
Is there a simple solution that I'm overlooking?
/// <summary>
/// Initializes a new instance of the HomeController class
/// </summary>
public HomeController(IObjectContext context)
{
_context = context;
}
/// <summary>
/// GET: /home/index
/// </summary>
/// <returns>Renders the home page</returns>
public ActionResult Index()
{
List contacts;
HomeViewModel model;
using (IRepository<Contact> repository = new DataRepository<Contact>(_context))
{
contacts = new List(repository.GetAll());
}
model = new HomeViewModel(contacts);
return View(model);
}
If I have to go the route of adding additional constructor overloads to accommodate my concerns, I was considering adding a number of private properties (which would deffer instantiation of the repositories until they are needed) to my controllers for each of the repositories that action methods make use of. For example:
private IRepository<Contact> _contactRepository;
private IRepository<Contact> ContactRepository
{
get
{
return _contactRepository ?? (_contactRepository = new DataRepository<Contact>());
}
}
For unit testing purposes, I'd be able to pre-initialize the repositories using the constructor overloads.
What are your thoughts on this? Am I missing something cleaner that should be obvious?
First of all, get rid of your current Bastard Injection constructor overloads. With DI, you should only need one constructor, and that's the one that takes all the dependencies. (To enable the ASP.NET MVC run-time to create the Controllers, implement a custom IControllerFactory.)
The next step is to inject all your dependencies through the constructor. When you think it gets messy because there are too many constructor parameters, it's a good sign that you are violating the Single Responsibility Principle. When that happens, you extract an Aggregate Service.
Rinse and repeat :)
Well, I do what your final example shows all the time to inject mocks into my controllers. It does have a little smell to it (designing for testability), but it isn't bad coding and works great for testing.
Your use of a generic repository is more a dependency-cloaking device than a dependency injection. You should be able to see all of the dependencies a particular Controller uses: a generic repository hides this fact somewhere deep in the entrails of your Controllers which makes maintaining (and unit-testing) the code much more difficult. My suggestion: use concrete repositories.
You could also take a look at domain-driven design stuff.