class instance per request in asp.net mvc - asp.net-mvc

I'm new with asp.net mvc. I have an app class which only needs one instance per request. It has IDispose so i'll need it to be dispose properly and I call it every page hit.
The problem I am finding is I sometimes needs to call methods in my view. I have no idea how I can access the class in the controller, view and have it dispose properly at the end of each request. I get the feeling I need to replace ALL of my controllers with my own controller class as a base. But this would only work if it executes the view first and I can access members in MyController from the view (actually I can just stuff it into the viewbag can't I)
Whats the proper way of doing this?

One solution would be to wire up a Dependency Injection framework (such as Ninject) and let it control the object lifetime for you. Ninject has a InRequestScope lifetime policy, which will create one object per request, so subsequent calls to get the object will return the same object if it is in the same request.

After implementing the dependency injection you can dispose your dependencies or objects like below in the controller.
protected override void Dispose(bool disposing)
{
_requestRepository.Dispose();
base.Disposing(disposing);
}

Related

What is the correct place to dispose a repository created in a custom controller factory?

In my ASP.NET MVC project I use a custom controller factory that instantiates an Entity Framework-based data repository and passes it to the controller's constructor. The repository object implements IDisposable, but where should I call its Dispose method? The most straightforward approach that comes to mind is to override the controller's Dispose method and do it there, but since the repository was injected into the controller and not created there, disposing it in the controller doesn't seem quite right to me.
In your repository, you should use the Entity Framework data contexts within a using statement. This means that after the data access is finished the Dispose method will be called on the context, closing the connection.
using(var context = new MyDbContext())
{
//do your data access
}
I guess is a little late by now, but you do it in the ReleaseController method of your IControllerFactory.
Take a look at this: http://www.jasinskionline.com/technicalwiki/(S(wvw00ibwlzs5na45orv53qyl))/Custom-Controller-Factory-Putting-Controllers-in-an-External-Assembly-ASP-NET-MVC.ashx?AspxAutoDetectCookieSupport=1

Using statement in Entity Framework

I would like to ask about "using" statement in Entity Framework. As I saw several time in other forums and books, that it's a good practice when you are quering database using following code (from ASP.NET MVC4 Appliocation):
using (var db = new ProductsEntites())
{
var result = db.Products.ToList();
return View(result);
}
But in other hand, if we are using scaffolding to generate contorller methods and view, default generator is declaring
private ProductsEntites db = new ProductsEntites()
at controller level, so in this case memory that are used to store query results are released only when timeout usage expired and garbage collector unlock memory for other needs. So what is better for small web site and what is best for big
You can override Dispose method of the controller. It should be called in the end of request.
protected override void Dispose(bool disposing) {
if(disposing)
db.Dispose();
}
having
private ProductsEntites db = new ProductsEntites()
as a class variable and Dispose it in the controllers Dispose Method seems fine to me. Like Mehmet Ataş pointed out:
protected override void Dispose(bool disposing) {
if(disposing)
db.Dispose();
}
The controller is disposed after the execution of an action.
The Entity Framework was developer to works fine even you not call the Dispose method (when you using a using statement you are implicity calling Dispose method).
It works fine because the EF use a Design Pattern call Fly Weight. In essence a piece of data always remains in memory. It's because that the EF has a delay in first execution of server, and when you kill de aplication has a delay to.
So you can use the code like scaffolding template without worrying about.
be wary of the using statement with EF, ensure that all your IQueryable returns are materialised by converting them into an IEnumerable by using ToList or ToArray etc.
If you don't, lazy loading could try and access the context to grab some navigation properties as they are used, if the context is disposed, you will get an exception thrown.

What is the best way to instantiate and dispose DbContext in MVC?

MVC 3 + EF 4.1
I'm choosing between two approaches to deal with DbContext:
Instantiate in Application_BeginRequest, put it into
HttpContext.Current.Items and dispose in Application_EndRequest.
Create disposable UnitOfWork (kindof wrapper for DbContext) and
start each controller action with using(var unitOfWork = new
UnitOfWork()) { ... }
Share your experience please: Which one would you prefer? what are pros and cons for each approach?
I would suggest you use a Dependency Injection framework. You can register your DbContext as per request
container.RegisterType<MyDbContext>().InstancePerHttpRequest();
And inject it as a constructor parameter to the controller.
public class MyController : Controller
{
public MyController(MyDbContext myDbContext)
{
_myDbContext = myDbContext;
}
}
If the registered type implements IDisposable then the DI framework will dispose it when the request ends.
1st approach: It is much more cleaner to use ID framework than manually implementing it. Further all your requests may not need your UoW.
2nd approach: The controller should not know how to construct your UoW(DbContext). Purpose is not reduce the coupling between components.
We currently use repositories injected with UoW (unit of work) instantiated via service locator from an repository factory. Unity controls the lifetime this way taking the work away from you.
Your particular implementation will vary depending if your using POCO's, Entity Objects, etc..
Ultimately you want UoW if your going to be working with more than one objectset in your controller to ensure your just using one context. This will keep your transactions in check etc.
If your going to use multiple objectcontexts (ie. multiple EDMX's), you'll want to look at using UoW with MSDTC...but thats probably more than you wanted to know. In the end, the important thing is to ensure you just instantiate what you need for the controller action (i.e. one instance of the context.). I don't think I'd go with Begin_Request, you may not even need the context for every request.
Don't put DbContext in global.asax! :
Static field of DbContext in Global.asax versus instance field of DbContext in controller class?
Entity framework context as static

ASP.net MVC Controller - Constructor usage

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).

Architecting medium size asp mvc - using ninject and creating objects

I'm designing medium-size website using asp.net mvc technology.
All business logic is organized into IServices (like IDomainService, IUserService, IAuthService, ITrainingService). All services are using IRepositories.
I'm using Ninject 1.5 to wire services with controllers and it seems working perfectly.
There is so far one subject I have no idea how to handle. Some services create contexts (per request) - for instance IDomainService creates DomainContext (per request) which is needed for IUserService.
ITrainingService is used only in TrainingController, which is accessible only by authorized users, and ITrainingService requires UserContext (also per request) to know who is having training.
This is my first project using IoC container.
Is there any design pattern or code-schema how to solve it?
I think I can fill context object using ActionFilters but how to manage their lifetime and where to put them to be accessible for IServices? (in an ellegant way)
I've used Ninject specifically in an MVC application. The way you'd accomplish this with Ninject is in the configuration or binding of your dependencies. When you do this, you specify how you want your object lifetimes to be managed. In most cases of a web app, you objects will be per request as you've indicated in your question.
One thing I've noticed in your question is that your DomainContext is being created by an IDomainService object and is used by other objects. If the domain service object is a sort of factory for a DomainContext, then you don't have much of a problem -- this becomes an exercise of how you configure Ninject to provide concrete objects and inject dependencies.
Here's general guidance on how you would structure your application -- bear in mind I don't have full understanding of your interfaces and classes:
public class GlobalApplication : NinjectHttpApplication {
protected override void RegisterRoutes(RouteCollection routes) {
// Your normal route registration goes here ...
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
// This function is resposible for creating a Ninject kernel. This is where
// the magic starts to happen.
protected override IKernel CreateKernel() {
var modules = new IModule[] {
new AutoWiringModule(),
new AutoControllerModule(
Assembly.GetExecutingAssembly()),
new ServiceModule()
};
return new StandardKernel(modules);
}
}
Note above that the easiest way to get Ninject to work is to derive your application class from the NinjectHttpApplication class. You will need to change your RegisterRoutes to an override method and will also be required to implement a method called CreateKernel. The CreateKernel method is responsible for returning the Ninject kernel which is itself the IoC container.
In the CreateKernel method, the Ninject-provided AutoControllerModule scans assemblies for MVC controller classes and registers them with the container. What this means is that dependencies on those controllers can now be injected by Ninject as it has become the controller provider for the application. The ServiceModule class is one that you need to create to register all of your services with Ninject. I'm guessing it would look something like this:
internal class ServiceModule : StandardModule {
public override void Load() {
Bind<IDomainService>()
.To<MyDomainService>()
.Using<OnePerRequestBehavior>();
Bind<DomainContext>()
.ToMethod( ctx => ctx.Kernel.Get<IDomainService>().CurrentDomainContext )
.Using<OnePerRequestBehavior>();
Bind<IService>()
.To<MyServiceType>()
.Using<OnePerRequestBehavior>();
}
}
Ninject's got a pretty expressive fluent interface for configuration. Note above that each statement basically associates a concrete class with an interface it implements. The "Using" phrase in the statement indicates to the Ninject kernel that the object will live for the life of the request only. So, for example, this means that anytime an IDomainService object is requested from the Ninject kernel during the same request, the same object will be returned.
As for you context objects, I'm taking a stab that your domain service creates these contexts and acts as a factory of sorts. In that regard, I bound instances DomainContext classes above to be produced by getting the value of the a property called CurrentDomainContext off the IDomainService. That's what the lambda above accomplishes. The nice thing about the "ToMethod" binding in Ninject is that you have access to a Ninject activation context object that allows you to resolve objects using the kernel. That's exactly what we do in order to get the current domain context.
The next steps are to ensure your objects accept dependencies properly. For example, you say that ITrainingService is used only in the TrainingController class. So, in that case I would ensure that TrainingController has a constructor that accepts an ITrainingService parameter. In that constructor, you can save the reference to the ITrainingService in a member variable. As in:
public class TrainingController : Controller {
private readonly ITrainingService trainingService;
public TrainingController(ITrainingService trainingService) {
this.trainingService = trainingService;
}
// ... rest of controller implementation ...
}
Remember that Ninject has already registered all of your controllers with the Ninject kernel, so when this controller is created and it's actions are invoked, you'll have a reference to the ITrainingService by way of the trainingService member variable.
Hope this helps you out. Using IoC containers can become quite confusing at times. Note, I highly recommend you check out the Ninject documentation -- it's a very well written introduction to Ninject as well as DI/IoC concepts. I've also left out discussion of the AutoWiringModule shown above; however, Nate Kohari (Ninject's creator) has a good write-up on his blog about this feature.
Good luck!
Im not exactly sure if I understand your problem completely, hopefully this bit of advice can help.
When using an IoC container you let the container handle object lifetime managment. I have only used Castle Windsor and StructureMap for dependency injection so I cant give you a concrete example for how to do this with Ninject.
Looking through the Ninject documentation I think you want to look at Activation Behaviours to specify object lifetime management.
Hope this helps.

Resources