I have a base controller from which inherit all my controllers. This base controller has some properties I'd like to inject the using property injection.
My controller registration looks like this
builder.RegisterControllers(Assembly.GetExecutingAssembly()
I don't know how to access the base class and inject the properties.
This should work:
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
Some more info on the autofac website: http://code.google.com/p/autofac/wiki/PropertyInjection
You may want to consider using an Autofac Aggregate Service:
An aggregate service is useful when you need to treat a set of dependencies as one dependency. When a class depends on several constructor-injected services, or have several property-injected services, moving those services into a separate class yields a simpler API.
An example is super- and subclasses where the superclass have one or more constructor-injected dependencies. The subclasses must usually inherit these dependencies, even though they might only be useful to the superclass. With an aggregate service, the superclass constructor parameters can be collapsed into one parameter, reducing the repetitiveness in subclasses. Another important side effect is that subclasses are now insulated against changes in the superclass dependencies, introducing a new dependency in the superclass means only changing the aggregate service definition.
This works for me:
using Autofac;
using Autofac.Integration.Web;
using Autofac.Integration.Web.Mvc;
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker();
nickvane's answer is correct. Just make sure
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
is after your all dependencies are registered. Or in other words, just right before you build your container.
So final code will look like
.
.
.
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
var container = builder.Build();
Need to call also for MVC:
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
For Web API:
HttpConfiguration config = GlobalConfiguration.Configuration;
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
Related
I'm having troubles getting the advantage of a IoC (DI) container like Ninject, Unity or whatever. I understand the concepts as follows:
DI: Injecting a dependency into the class that requires it (preferably via constructor injection). I totally see why the less tight coupling is a good thing.
public MyClass{
ISomeService svc;
public MyClass(ISomeService svc){
svc = svc;
}
public doSomething(){
svc.doSomething();
}
}
Service Locator: When a "container" is used directly inside the class that requires a dependancy, to resolve the dependancy. I do get the point that this generates another dependancy and I also see that basically nothing is getting injected.
public MyClass{
public MyClass(){}
public doSomething(){
ServiceLocator.resolve<ISomeService>().doSomething();
}
}
Now, what confuses me is the concept of a "DI container". To me, it looks exactly like a service locator which - as far as I read - should only be used in the entry point / startup method of an application to register and resolve the dependancies and inject them into the constructors of other classes - and not within a concrete class that needs the dependancy (probably for the same reason why Service locators are considered "bad")
What is the purpose of using the container when I could just create the dependancy and pass it to the constructor?
public void main(){
DIContainer.register<ISomeService>(new SomeService());
// ...
var myclass = new MyClass(DIContainer.resolve<ISomeService>());
myclass.doSomething();
}
Does it really make sense to pass all the dependancies to all classes in the application initialization method? There might be 100 dependancies which will be eventually needed (or not) and just because it's considered a good practice you set create them in the init method?
What is the purpose of using the container when I could just create the dependancy and pass it to the constructor?
DI containers are supposed to help you create an object graph quickly. You just tell it which concrete implementations you want to use for which abstractions (the registration phase), and then it can create any objects you want want (resolve phase).
If you create the dependencies and pass them to the constructor (in the application initialization code), then you are actually doing Pure DI.
I would argue that Pure DI is a better approach in many cases. See my article here
Does it really make sense to pass all the dependancies to all classes in the application initialization method? There might be 100 dependancies which will be eventually needed (or not) and just because it's considered a good practice you set create them in the init method?
I would say yes. You should create the object graph when your application starts up. This is called the composition root.
If you need to create objects after your application has started then you should use factories (mainly abstract factories). And such factories will be created with the other objects in the composition roots.
Your classes shouldn't do much in the constructor, this will make the cost of creating all the dependencies at the composition root low.
However, I would say that it is OK to create some types of objects using the new keyword in special cases. Like when the object is a simple Data Transfer Object (DTO)
I am using dependency resolver and i have added my unity container to the same. So by default "GoldCustomer" gets injected in to the "CustomerController" as per the current container rules.
IUnityContainer oContainer = new UnityContainer();
oContainer.RegisterType<ICustomer, GoldCustomer>(); // injects GoldCustomer
DependencyResolver.SetResolver(new UnityDependencyResolver(oContainer));
If i want to change by current container configuration i can always create new Container and set it and call the SetResolver again. I know that the above code should be configurable via XML config but still if we need to pickup new container objects we have to still call the setresolver.
Is this the right way or are there better ways of changing container depedency rules while the application running.
Second what are the events where we can change the container is it session_start , httphandler's or something better.
Firstly why would you need multiple containers? It must be the singleton object who keeps all the dependency registered since the application started.
In a practice I would say keep single container and if required create multiple Registration function in separate assemblies and invoke all of them in a AppBootstrapper.
If it's an application then best way is to use the Application start with Async behaviour so that the startup doesn't get affected.
======================================================
Unfortunately the Named registration is the only option and Unity required to register with names explicitly. Thats why I personally like DI containers like Autofac and SimpleInjector. They are fast and They allow multiple registrations of an Interface with multiple Types and the resolver uses Type resolver and Named resolver methods without explicitly asking for Names and those resolvers are overridable too.
I am not sure why it does not look that complex to me , If I understand question quickly I can do it as follows,
assume that I have interface IMovieRepository and two classes implementing it EnglishMovieRepository and HindiMovieRepository.
How about resolving them as in UnityConfig.cs as follows,
If(condition)
{
container.RegisterType<IMovieRepository, EnglishMovieRepository>();
}
else
{
container.RegisterType<IMovieRepository, HindiMovieRepository>();
}
If requirement is something different then please let me know
Thanks
/dj
We have a project written in ASP.NET MVC and we use NInject to inject the repositories into the controllers. Currently we are using properties and the Inject-attribute to inject the repositories, which works well enough:
[Inject]
public IMyRepository MyRepos {get;set;}
An alternative way of injecting would be to do it "manually" using the NInjectServiceLocator:
var myRepos = NInjectServiceLocatorInstance.Resolve<IMyRepository>();
Now I was wondering about the following: the first method requires all repositories to be listed at the top (not necessarily at the top of course, but it's the most logical place) of a controller. Whenever a request is made, NInject instantiates each and every repository. This happens regardless of whether all of the repositories are actually needed inside a specific Action.
With the second method you can more precisely control which repositories are actually necessary and thus this might save some overhead when the controller is created. But you probably also have to include code to retrieve the same repository in multiple places.
So which one would be better? Is it better to just have a bunch of repository-properties or is it better to resolve the repositories which are actually necessary for a specific action when and where you need them? Is there a performance penalty involved for injecting "useless" repositories? Are there (even ;-) better solutions out there?
I prefer constructor injection:
private readonly IMyRepository _repository;
public MyController(IMyRepository repository)
{
_repository = repository;
}
All your dependencies are listed in one operation
Your controller does not need to know anything about NInject
You can unit-test your controller without NInjects involvment by stubbing interfaces straight to the constructor
Controller has a cleaner code
NInject or any other DI framework will do the work behind the scenes and leave you concentrating on the actual problem, not DI.
Constructor Injection should be your default choice when using DI.
You should ask yourself if the controller is really dependent on that specific class to work at all.
Maybe Method injection could also be a solution for specific scenario's, if you have only specific methods that needs dependencies.
I've never used Property Injection but Mark Seeman describes it in his book (Dependency Injection in .NET):
PROPERTY INJECTION should only be used when the class you’re developing has a good
LOCAL DEFAULT and you still want to enable callers to provide different implementations
of the class’s DEPENDENCY.
PROPERTY INJECTION is best used when the DEPENDENCY is optional.
NOTE There’s some controversy around the issue of whether PROPERTY INJECTION
indicates an optional DEPENDENCY. As a general API design principle, I
consider properties to be optional because you can easily forget to assign
them and the compiler doesn’t complain. If you accept this principle in the
general case, you must also accept it in the special case of DI. 4
A local default is described as:
A default implementation of an ABSTRACTION that’s defined in the same assembly as
the consumer.
Unless you're building an API I would suggest not to use Property Injection
Whenever a request is made, NInject instantiates each and every repository. This happens regardless of whether all of the repositories are actually needed inside a specific Action.
I don't think you should worry to much about the performance when using constructor injection
By far my favorite method is:
public class MyController : Controller
{
public IMyRepository MyRepos {get;set;}
public MyController(IMyRepository repo)
{
MyRepos = repo;
}
}
So you can use a NuGet package, such as Ninject.MVC3 (or MVC4) which has specific support for including the Ninject kernel inside the MVC's own IoC classes
https://github.com/ninject/ninject.web.mvc/wiki/MVC3
Once you have Ninject hooks in, you can let it do the work of injection instances into the controller's constructor, which I think is a lot cleaner.
EDIT:
Ahh, OK. Having read your question a bit more thoroughly, I see where you're going with this. In short, if you want to pick and choose which repo classes are instansiated then you will need to manually call, for example:
var myRepos = NInjectServiceLocatorInstance.Resolve<IMyRepository>();
You cannot configure Ninject (or any other IoC AFAIK) to selectively create object instances based on the currently execute method. That level of granularity is a real edge case I feel, which may be solvable by writing your own controller factory class, but that would be overkill.
There are many discussions around here about this, but none seem to really answer the question.
I'm currently considering using the Symfony 2 service container. The more I look at it though, the more it seems like I could just do the same thing with a service factory. Consider the following example:
services.yml
services:
my_mailer:
class: Acme\Mailer
arguments: [sendmail]
newsletter_manager:
class: Acme\Newsletter\NewsletterManager
arguments: [#my_mailer]
Now to get a newsletter manager, I do something like:
// this has been configured with the above yml file
$serviceContainer = new ServiceContainer();
$newsletterManager = $serviceContainer->get("newsletter_manager");
However, consider the following factory style code:
class ServiceContainer
{
public function getMyMailer()
{
return new Acme\Mailer("sendmail");
}
public function getNewsletterManager()
{
return new Acme\Newsletter\NewsletterManager($this->getMyMailer());
}
}
And then using it:
$serviceContainer = new ServiceContainer();
$newsletterManager = $serviceContainer->getNewsletterManager();
Is there something I'm missing here? Because I don't really see the advantage to using a DI container if a factory can do all of that for me.
I have heard using factories causes your code to "depend on the factory". I either don't understand this argument or the person arguing against factories is confused. Only the top level class (the composition root) would have a reference to the factory, just like it would be the only one with the reference to the DI container.
Is there something I'm missing here? Because I don't really see the
advantage to using a DI container if a factory can do all of that for
me.
Yes - you are using your DI container using the Service Locator (anti-)pattern instead of injecting your dependencies into your classes. Your class should not have to reference your DI container at all.
Instead there should be just a single aggregate root where you create the container and resolve all dependencies. Once you have resolved your top level class instance all of its dependencies (and the dependencies of the dependencies and so on) are then resolved using the IoC container using the Hollywood Principle - when class instances are created all of its dependencies are passed in, the instance never asks for a dependency itself.
I am trying to Bind two concrete classes to one interface. What command should I use in Ninject to do that? What I am trying to do is to Bind two concrete classes to one interface base on the controller Name. Is that possible? I suppose that in ninject you use the .When to give the conditional but there is no tutorial out there where they show you how to use the .When for ninject.
Here are few examples. Check out Ninject source project and its Tests subproject for various samples of usage, that's the best documentation for it, especially since docs haven't been updated for v2 yet.
// usage of WhenClassHas attribute
Bind<IRepository>().To<XmlDefaultRepository>().WhenClassHas<PageAttribute>().WithConstructorArgument("contentType", ContentType.Page);
// usage of WhenInjectedInto
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(ServicesController));
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(PageController)).WithConstructorArgument("contentType", ContentType.Page);
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(WidgetZoneController)).WithConstructorArgument("contentType", ContentType.WidgetZone);
// you can also do this
Bind<IRepository>().To<PageRepository>().WhenInjectedInto(typeof(PageController)).WithConstructorArgument("contentType", ContentType.Page);
Bind<IRepository>().To<WidgetZoneRepository>().WhenInjectedInto(typeof(WidgetZoneController)).WithConstructorArgument("contentType", ContentType.WidgetZone);
// or this if you don't need any parameters to your constructor
Bind<IRepository>().To<PageRepository>().WhenInjectedInto(typeof(PageController));
Bind<IRepository>().To<WidgetZoneRepository>().WhenInjectedInto(typeof(WidgetZoneController));
// usage of ToMethod()
Bind<HttpContextBase>().ToMethod(context => new HttpContextWrapper(HttpContext.Current));
HTH