What is the correct way of Instantiate Controller with IoC - inversion-of-control

I am migrating to ASP.NET MVC 3.
Now I have some ways of resolve controller with IoC.
My controller need a contructor injection parameter for repositories.
Setting DependencyResolver.SetResolver works. But I donĀ“t know if this is correct way or I need to Register a IControllerActivator at my container too.

What you need is a ControllerFactory.Most IOC containers have an existing implementation. If you need a custom one, check this article:
http://develoq.net/blog/?p=144
Update
It's the correct way. DependencyResolver is generic for everything, and you need to register the IControllerActivator in it.
http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html

Related

Build new Object Instances in Zend Service Manager Component

I would like to know in best practice questions and think of easily testable classes, when I need multiple different instances of the same (fabricated) object within a specific class, which approach is recommended?
Before I used the Service Manager build method, but it is no longer recommended to inject Service Manager directly into a class, right?

MEF and MVC - a few pointers please :)

What I am trying to do is inject a component into my MVC app and make use of it from the controllers.
Currently I am not trying to use MEF for the actual controllers, but i want to import components e.g. A loggin component into the MVC app.
Where is the best place to do this?
Currently I have, directly in the controller, put my compose parts code and ILogger property, but I get the feeling this is not the best way. Seems like I should only need to call Compose once in the application.
So should it be in the global asax file that I do the compose?
If so, how do I get a handle on ILogger from my controllers? Should I have a "base" controller, where i inject ILogger into the constructor and inherit every standard controller from?
Hope that makes sense - I'm just struggling a bit with the structure of my code.
Thx
I use Log4Net and inject the logger into each controller. I dont think its a big hit when you use injection. Take a look at Ninject. It has both an MVC implementation and a logging module. The modules are loaded once in the global, then it injects the controllers. Basic DI, but do you really need more? If you create a base controller you will still have to create a ctor in each controller that can be injected.
You might create a base controller with the logging, then use property injection. I have never done this, but if all controllers use the same base it should work fine.

How to provide ASP.NET MVC2 master pages with a model indepdent of the controller

I'm using strongly typed views and autofac for Dependency Injection under ASP.NET MVC2 and I'm trying to get a common dynamic header via dependency injection. I.e. i want this to happen without the view having to be away of this content even existing and i was hoping to avoid static discovery of the container and manual resolution, but I can't find a way to easily inject the master or a partial view included in the master via either ctor or property injection.
I can't imagine this is an uncommon task, but all I can find in terms of methods is Controller subclassing to stuff data into untyped ViewData, subclassing ViewModels to stuff master data into the model, or static resolution, all of which I'd prefer not to use. What am I overlooking?
EDIT: As has been pointed out DI into master pages is fighting the framework. So my question is badly framed: I don't really care about DI into master pages, but I have a dynamic element in the chrome of the site, i.e. the master page. Providing it with a model shouldn't be the responsibility of each controller using that master, as it is request context, not controller context specific. I fully admit that injection directly into master pages is inappropriate. If i could register a separate master controller to be invoked in addition, that would be even better. Is that possible? Given this task of providing the master with a model independent of the controller, what is the framework appropriate approach? Or does shared content in MVC require that each Controller has to know about that content?
You could use child actions.
Controller:
public class MyHeaderController: Controller
{
private readony IRepository _repository;
public MyHeaderController(IRepository repository)
{
_repository = repository;
}
[ChildActionOnly]
public ActionResult Index()
{
var model = _repository.GetSomeModel();
return PartialView(model);
}
}
And somewhere in your master page include it:
<div><%= Html.Action("Index", "MyHeader") %></div>
Your problems stem from confusing the term Dependency Injection, and fighting how the ASP.NET MVC framework works.
Also, you are using the term Dependency Injection in the wrong context. You are trying to use a hammer as a chisel.
MasterPages and views in ASP.NET MVC are intended to be used as templates. As stated in the other answer, child actions will solve your problem.
For future reference:
Dependency Injection refers to a means to configure what parameters to inject into class constructors, and have this done for you automatically, overriding some of the frameworks defaults. The purpose for this is to decouple components, so that they become more reusable, more testable, more unitary, amongst other good things.
DI refers to, and solves, a code issue, not a UI issue.
What you are trying to do is simply not possible. Ie, inject via constructors and properties a "dependency" into a masterpage. Again, MasterPages are intended by ASP.NET MVC to be used as just templates. They have no code behind class to instantiate via a constructor that would allow dependencies to be injected into it.
In other words, you are fighting the framework, which means you don't understand it.
If this sounds like nitpicking, I think this has to be highlighted as otherwise, you are confusing yourself and others who read this thread in the future.

Where to set the ModelMetadataprovider with DI when using MVC Turbine?

To use your own ModelMetadataProvider you normally set it in the global.asax.
I'm using MVC Turbine and I need to inject a dependency into my ModelMetadataProvider as well.
Something like this:
ModelMetadataProviders.Current = new MyModelMetadataProvider(ISomeDependency);
How is this best accomplished with MVC Turbine?
The best place to put these pieces is to override the Startup method within your web application (the type that inherits from TurbineApplication). We're currently working on making these MVC2 features easier in v2.2 by introducing a ModelMetadataBlade that will do all the wiring up for you to the ModelMetadataProvider.Current property.
So all you'll have to do is register MyModelMetadataProvider with the container like so
container.Register<ModelMetadataProvider, MyModelMetadataProvider>()
then MVC Turbine will do the rest for you. To get an idea of what I'm talking about, checkout the way we're wiring up ModelValidatorProviders. The ModelValidatorBlade asks the ServiceLocator for all the registered ModelValidatorProvider and wires them up with the runtime.
If you have any feedback or ideas, could you post them to the Google Group? Trying to keep these things organized :)
Thanks!

Using Castle Windsor to inject IRailsEngineContext

Issue
I am using Castle Windsor as an IoC container in a Castle Monorail project. I would like to inject the current instance of IRailsEngineContext into an object being resolved from the container in a controller.
Context
The object I would like inject the rails context into would be used to wrap the session object for the purpose of retaining the ids of previously viewed records. It would then be referenced to ensure that they aren't viewed again.
Alternate Solutions
I could pass the context to the methods with each call or inject it manually, but it would be nice to inject it directly from the container.
Question
I can't think of a way to inject the context within the container. Is there a way to do this? Does this even make sense?
Container.Register(
Component.For<IRailsEngineContext>()
.UsingFactoryMethod(()=>MonoRailHttpHandler.CurrentContext)
.LifeStyle.Transient
);
IRailsEngineContext - that's from an old version of MonoRail I guess. I'd advise you move to a newer one, the sooner the better.