I have an ASP.NET MVC5 project with Unity as DI framework.
Consider the following code:
container.RegisterType<ApplicationDbContext>(
new InjectionFactory(c => new ApplicationDbContext()));
As my repositories are using the same DbContext, it would be practical to pass the same instance to all of them. However, every visitor of the site should have a separate instance of the context, not work on one big "site-wide" instance. I guess this reduces the possibilites to have an instance lifetime only for the current request.
As UnityConfig.RegisterComponents() is in the Application_Start() method, I guess it would only create one instance for the entire application.
What is the best practice in this case? I have thought about the following:
Create my own factory for the DbContext which returns a singleton, and inject this factory into my repositories
Move UnityConfig.RegisterComponents() to Application_BeginRequest()
I tried to search for InjectionFactory on Microsoft's site, not much luck (http://msdn.microsoft.com/en-us/library/microsoft.practices.unity.injectionfactory%28v=pandp.51%29.aspx)
What best practice should I follow in this case? I don't want to overengineer it, what is the simplest working solution?
I'm not a web developer but reading through the book Dependency Injection With Unity they did mention a special lifetime manager that you can use for a single HTTP request - PerRequestLifetimeManager
Perhaps that would work for your needs?
Remove the factory and replace with:
container.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager());
This will result in an ApplicationDbContext instance per request and also take call of disposing of the context at the end of the request.
I think what you're after is the unit of work pattern.
Take a look at the following link
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Related
I have a situation where I need to manually instantiate some objects in Application_BeginRequest that are dependent on some of the same components that I've registered with Autofac. I'd like to use the same instances of components that I've registered with Autofac with InstancePerLifetimeScope for injection into my MVC and WebAPI controllers. My config for both MVC and Web API works as expected, and an example of a component registration looks like so:
builder.Register(c => new MyDbContext()).AsSelf().InstancePerLifetimeScope();
Now I want to use that same instance in the class I'm instantiating in Application_BeginRequest. I've tried the following methods:
//Tried with MVC controllers
DependencyResolver.Current.GetService<MyDbContext>()));
AutofacDependencyResolver.Current.ApplicationContainer.Resolve<MyDbContext>()));
AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<MyDbContext>()));
//Tried with Web API controllers
GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(MyDbContext))
But none give me what I'm looking for, even at later points in the request lifecylce (ie, beyond BeginRequest). As an aside, I need this to work with the Web API configuration, but I tried the first 3 methods just to see if I could get any of the resolved instances to match up with what Autofac is injecting.
I have what I believe is a decent understanding of lifetime scopes in Autofac and my assumption is that the instances that are being resolved for my application's controllers are in a child scope that the none of the above 4 methods are pointed towards, but it's fuzzy to me what each of the above methods is trying to do in regard to which scope they are looking at and how they decide. What's even fuzzier is what lifetime scopes Autofac is automatically creating for the components that are ultimately injected into my controllers and when they're created.
Clarification on the points above would be a big bonus, but my primary question here is how do I get Autofac to hand me the same instances of registered components in Global.asax that it resolves for Web API and MVC controllers?
If you read up on this subject, you'll notice that folks mention that in most circumstances for a web application, InstancePerLifetimeScope and InstancePerRequest can be used interchangeably. What they don't mention are the exceptions where these two registrations behave differently. Gerrod has an excellent article on lifetime scopes inside of ASP.NET MVC/Web API applications and how they work in which he elaborates on this piece of info that most omit. Understanding this difference is crucial to this scenario, and his article cleared up any misunderstandings I had in regards to InstancePerLifetimeScope registration in relation to ASP.NET applications. It also made me realize that, because I need to share instances of resolved components across my MVC/Web API controllers and within the global.asax, InstancePerLifetimeScope is no longer a suitable means of registration for this application- I now need to use InstancePerRequest.
As per the docs, InstancePerRequest actually uses InstancePerMatchingLifetimeScope under the hood. What I need is a reference to the child scope that is tagged with "AutofacWebRequest" that lives under the root scope. This is the scope that both my MVC and Web API controllers resolve their dependencies from, since they both use the same tag. So how do I get a reference to that particular scope? This was my solution, and I'd love to know if there's a better way to do it.
First off, I need to change my registration from
builder.Register(c => new MyDbContext()).AsSelf().InstancePerLifetimeScope();
to
builder.Register(c => new MyDbContext()).AsSelf().InstancePerRequest();
Now, after I've built my container I have the following method:
private void SetDependencyResolversForMvcAndWebApi(ILifetimeScope container)
{
container.ChildLifetimeScopeBeginning += CaptureRequestLifetimeScope;
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
The only part that wasn't there before is the event subscription. Everytime my container creates a child scope, my event handler gets called. The event handler looks like this:
private void CaptureRequestLifetimeScope(object sender, LifetimeScopeBeginningEventArgs args)
{
if (args.LifetimeScope.Tag == MatchingScopeLifetimeTags.RequestLifetimeScopeTag)
{
//Get the ILifetimeScope created for components registered with InstancePerRequest
var requestScope = args.LifetimeScope;
//This is the same DbContext instance that will be injected into
//my WebAPI and MVC controllers
var context = requestScope.Resolve<MyDbContext>();
//do the rest of my stuff
}
}
I've tested this by holding onto a reference of the resolved DbContext that's resolved within the CaptureRequestLifetimeScope event handler and comparing it to the DbContext instances that are injected into my Web API and MVC controllers, and they are indeed pointing to the same object.
Well, I think you should try changing .InstancePerLifetimeScope() into .InstancePerRequest();
As Autofac says about InstancePerLifetimeScope:
When you resolve the instance per lifetime scope component, you get a single instance per nested scope (e.g., per unit of work).
So when you do Resolve<MyDbContext>() you are probably doing it in a different Lifetime scope than you controller (I guess it's because you're doing an explicit resolution); that's why you're getting a diffent instance.
InstancePerRequest instead:
Some application types naturally lend themselves to “request” type semantics, for example ASP.NET web forms and MVC applications. In these application types, it’s helpful to have the ability to have a sort of “singleton per request.”
The begin phase of your request is already in the request phase, so you shoud get the same instance there and inside your controllers.
Instance per request builds on top of instance per matching lifetime scope by providing a well-known lifetime scope tag, a registration convenience method, and integration for common application types.
Based on this, probably, you can also go for the .InstancePerMatchingLifetimeScope("myrequest"), but you will have to manually instanciate a Lifetime scope everywhere like this using(var scope1 = container.BeginLifetimeScope("myrequest")); I think is not so practical.
Obviously I suppose you will not use those elements outside of the request scope, or you will get an exception. In that case, you are forced to the MatchingLifetimeScope.
If you need more details, the Autofac guide is extremely clear.
DependencyResolver.Current.GetService<MyDbContext>()));
AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<MyDbContext>()));
are same. They get current request lifetime scope. If you resolve some instance here, it shares it with cotrollers. (In this stiuation, instance per request and instance per lifetime will be same. Because their lifetime is same).
AutofacDependencyResolver.Current.ApplicationContainer.Resolve<MyDbContext>()));
This wil be resolved from root container. That's why it will create another instance for request lifetime scope. This will not be shared. And this will live in root container. (If you have per request instance, this will give error).
I have tested first one. It shares instance resolved in Application_BeginRequest with mvc controllers but not with Api controllers.
Then I tried to get GlobalConfiguration.Configuration.DependencyResolver.GetRequestLifetimeScope() in Application_BeginRequest it returns null.
I think, if it's api request, Autofac doesn't start request lifetime yet in Application_BeginRequest (May be it's related .net).
So if it's api request and if we can't reach autofac request life time. I don't know how to share this instance with mvc and api controllers which is resolved in Application_BeginRequest.
May be Travis can make it clear.
I have started to go through Symfony2 code, studied a little bit small classes like Pimple and after few hours of examination have come to strange idea. The best start for this is to explain how I understand few terms, so:
Dependency
Something which is needed for another thing to work, like "engine" in "car"
Container
Object or class which is able to store a lot of another objects, like "engine","gearbox" or even "car"
Dependency Injection
Process in which every dependency is injected to object, so if I need "car" I know that I have to inject "engine","gearbox" and a lot of another stuff. Important is, that "car" don't create "engine", but "engine" is put inside "car"
Service Locator
Process in which object asks for another object, for example into the car there is inserted our container, and when car need to start it require from container "engine", so container return him "engine"
When i studied Symphony code, they start with dependency injection, but after some time I realize that when Controller is created, there is injected whole container and then you can use $this->get('serviceName') to get it, so it more looks like service locator, which according to few articles is anti-pattern.
Sow how is it? Is that line between DI and SL so small that it is sometimes broken? Or did I misunderstood something? If I use DI, do I need to insert every service into controller, so I know from outside what I use? Or can controller become in some cases container?
Your understanding of DI is pretty good. And yes, Symfony Controller does implement ContainerAwareInterface, and as you said, has a service locator role. But service locator isn't an anti-pattern. Each pattern has it's proper and improper uses.
Furthermore, Symfony doesn't enforce you in any way to use it's Controller. Your Controller can be a service. Hell, it can even be a function!
Here is one of the reasons why Controllers are implemented as service locators: Performance.
Let's drop car analogy and focus on real case that you'll encounter in 99% of projects: you need CRUD for a resource. Let's say you're building a Todo app and you need a RESTfulish controller to handle CRUD operations for Task Resource.
The least you need to have is a way to read all tasks and a way to add a new task, for that you need two actions: index (commonly named list too), and store (commonly named create too).
Common flow in Symfony would be this, in pseudo code:
indexAction -> getDoctrine -> getTaskRepository -> getAllTasks
storeAction -> getFormFactory -> createForm -> bindRequestDataToForm -> getDoctrine -> saveData
If Controller was a service locator
Index Action
When index action is executed, only service that will be resolved from the container will be ManagerRegistry (in this case Doctrine service). We will then ask it to give us task repository, and we'll do our operation with it.
Store Action
When store action is executed, we will do a bit more work: ask container to give us FormFactory, do some operations with it, and then ask it to give us Doctrine and do some operations with it too.
So summary: when index action is executed, only one service has to be constructed by service container, when update is executed, two will have to be constructed.
If Controller was a regular service
Let's see what our Controller needs. From the section above, we see that it needs FormFactory and Doctrine.
Now, when you just want to call index action to read all tasks from data storage, your controller will have to get instantiated by container. Before it can be instantiated, container needs to instantiate it's dependencies: FormFactory and Doctrine. Then instantiate controller while injecting those two into it.
So, you are calling index action which doesn't need FormFactory at all, but you still have overhead of creating it because it is needed for an action that will not be called at all in that request.
Lazy Services
To reduce this overhead, there is a thing called lazy service. It works by actually injecting a Proxy of your service into the controller. So, as far as controller is concerned, it got FormFactory. What it doesn't know is that isn't real FormFactory but instead a fake object which will delegate calls to real FormFactory code when you call some method on it.
Wrapping it up
Controller doesn't have to be a service locator, but can be. Making it a service locator can be a bit more performant and easier to bootstrap, but hides dependencies. Furthermore, it's a bit harder to test, since you'll need to mock dependency container. Whether you want to make your controllers services, functions or service locators is your choice and Symfony won't enforce you to use any of those ways.
In my experience, extending default Symfony Controller and having controllers be service locators is just fine as long as you don't write your business logic in them, but instead delegate all that work to services, which you get from container. That way, it's really unlikely that you'll have bugs in controller code (as methods will usually consist of 2-3 lines of code) and can get away without testing it.
Following the suggestion in "Dependency Injection in .NET", I am resolving the composition root in each page constructor like this:
public MyPageConstructor()
{
var container = (Castle.Windsor.WindsorContainer)HttpContext.Current.Application["DIcontainer"];
Controller = container.Resolve<MyPageController>();
}
Now, if I make the controller transient, I have to release it manually when the page is unloaded. If I make it per-request, Castle will release it for me when the request is over but there may be a performance penalty, I am not sure. At the moment I tend to make the objects transient and handle the release on my own.
Are there other things to consider and what would be the recommended practice?
Thank you.
I recommend to use the longest possible lifetime. Unfortunately, complex application can have more than one entry points, where the Resolve method has called. And if you chose Transient, there is a risk that some service would be created multiple times per request. For example, some HttpModule could use the same services, as a Page. With PerRequest lifetime such issue can be avoided.
It depends, if you have a class that has a lot of dependencies on it, the overhead of instantiating the same thing over and over, might be to severe. But if have something that isn't threadsafe you are better of as transient.
I trying to build an ASP.NET MVC application using Nhibernate and Structuremap along with the Repository pattern.
Through my initial approach to this project and the subsequent reading, I was wanting to keep the Nhibernate Session confined to the Repositories, and the Repositories to the Controller. But at the same time, in regards to transactions, I wanted to keep this separated from the repository methods (i.e. I just wanted to call session.Save()).
But It almost seems required that the Controller know about the session so that I can perform any transaction setup on the session before any Controller action, and any persistence to the database after the action using something like (i.e. the ActionFilterAttribute methods BeforeExecution or AfterExecuted, or BeginRequest/EndRequest events in the MvcApplication.
So in my mind I am having to give the current NHibernate Session to the Controller as well as the Repository, just so I can act on the Session when certain actions/results occur on the controller.
Is this the only way I can go about this?
I have read Ayende's blogs, and an assortment of different ways to go about this, but in the case of using the repository pattern, this almost seems like a must. I was hoping to be able to make the Nhibernate / StructureMap setup to the most pluggable way possible so with the exception of defining FluentNhibernate configuration for a specific project, there would be very minimal wiring for adding it to another MVC project.
That's ok. You'll need to open your session on your request begin and close it on your request end.
Ok, so the problem is:
I've got some 'order' entity, and it has 'status' property. On changing status, i wanted some other objects to be informed of this event, so i've decided to use Observer pattern. One of the observers notifies clients via email. Now i want to render Email text's from some of the twig templates. As i get from the Book, rendering templates in controllers are done with 'templating' service.
So the question as it follows: How can i access 'templating' service in my Observer class?
Specification:
I was advised, to implement my Observer as a service, but i'm not sure 'bout that. I've tried to solve this problem, and here is my options:
Use Registry. Solution that is straight and hard as rail. I guess it misses the whole point of DI and Service Container. Huge plus of this solution, is that i can access all common services from any point of my application.
To pass needed services from the context via constructor, or via setters. This is more like in Sf2 spirit. There comes another list of problems, which are not related to this question field.
Use observers as a service. I'm not really sure 'bout this option 'cos, in the book it is written, that service is a common functionality, and i don't think that observing entity with number of discrete properties is a common task.
I'm looking for a Sf2 spirit solution, which will be spread over whole project, so all answers with an explanation are appreciated.
As with any other service in a Symfony2 project, you can access it from within other classes through the dependency injector container. Basically what you would do is register your observer class as a service, and then inject the templating service into your observer service. See the docs for injecting services.
If you're not familiar with how Symfony handles dependency injection, I'd suggest reading that entire chapter of the documentation - it's very helpful. Also, if you want to find all the services that are registered for application, you can use the console command container:debug. You can also append a service name after that to see detailed info about the service.
Edit
I read your changes to the question, but still recommend going down the DI route. That is the Symfony2 spirit :) You're worried that your observer isn't common enough to be used as a service, but there's no hard rule saying "You must use this piece of code in X locations in order for it to be 'common'".
Using the DIC comes with another huge benefit - it handles other dependencies for you. Let's say the templating service has 3 services injected into itself. When using the DIC, you don't need to worry about the templating service's dependencies - they are handled for you. All you care about is telling it "inject the templating service into this other service" and Symfony takes care of all the heavy lifting.
If you're really opposed to defining your observer as a service, you can use constructor or setter injection as long as you're within a container-aware context.